diff --git a/.ci/compute-projects.sh b/.ci/compute-projects.sh new file mode 100644 index 0000000000000..32baf26b4f0a0 --- /dev/null +++ b/.ci/compute-projects.sh @@ -0,0 +1,194 @@ +#!/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 contains functions to compute which projects should be built by CI +# systems and is intended to provide common functionality applicable across +# multiple systems during a transition period. +# + +function compute-projects-to-test() { + isForWindows=$1 + shift + projects=${@} + for project in ${projects}; do + echo "${project}" + case ${project} in + lld) + for p in bolt cross-project-tests; do + echo $p + done + ;; + llvm) + for p in bolt clang clang-tools-extra lld lldb mlir polly; do + echo $p + done + # Flang is not stable in Windows CI at the moment + if [[ $isForWindows == 0 ]]; then + echo flang + fi + ;; + clang) + # lldb is temporarily removed to alleviate Linux pre-commit CI waiting times + for p in clang-tools-extra compiler-rt cross-project-tests; do + echo $p + done + ;; + clang-tools-extra) + echo libc + ;; + mlir) + # Flang is not stable in Windows CI at the moment + if [[ $isForWindows == 0 ]]; then + echo flang + fi + ;; + *) + # Nothing to do + ;; + esac + done +} + +function compute-runtimes-to-test() { + projects=${@} + for project in ${projects}; do + case ${project} in + clang) + for p in libcxx libcxxabi libunwind; do + echo $p + done + ;; + *) + # Nothing to do + ;; + esac + done +} + +function add-dependencies() { + projects=${@} + for project in ${projects}; do + echo "${project}" + case ${project} in + bolt) + for p in clang lld llvm; do + echo $p + done + ;; + cross-project-tests) + for p in lld clang; do + echo $p + done + ;; + clang-tools-extra) + for p in llvm clang; do + echo $p + done + ;; + compiler-rt|libc|openmp) + echo clang lld + ;; + flang|lldb|libclc) + for p in llvm clang; do + echo $p + done + ;; + lld|mlir|polly) + echo llvm + ;; + *) + # Nothing to do + ;; + esac + done +} + +function exclude-linux() { + projects=${@} + for project in ${projects}; do + case ${project} in + cross-project-tests) ;; # tests failing + openmp) ;; # https://github.com/google/llvm-premerge-checks/issues/410 + *) + echo "${project}" + ;; + esac + done +} + +function exclude-windows() { + projects=${@} + for project in ${projects}; do + case ${project} in + cross-project-tests) ;; # tests failing + compiler-rt) ;; # tests taking too long + openmp) ;; # TODO: having trouble with the Perl installation + libc) ;; # no Windows support + lldb) ;; # custom environment requirements (https://github.com/llvm/llvm-project/pull/94208#issuecomment-2146256857) + bolt) ;; # tests are not supported yet + *) + echo "${project}" + ;; + esac + done +} + +# Prints only projects that are both present in $modified_dirs and the passed +# list. +function keep-modified-projects() { + projects=${@} + for project in ${projects}; do + if echo "$modified_dirs" | grep -q -E "^${project}$"; then + echo "${project}" + fi + done +} + +function check-targets() { + # Do not use "check-all" here because if there is "check-all" plus a + # project specific target like "check-clang", that project's tests + # will be run twice. + projects=${@} + for project in ${projects}; do + case ${project} in + clang-tools-extra) + echo "check-clang-tools" + ;; + compiler-rt) + echo "check-compiler-rt" + ;; + cross-project-tests) + echo "check-cross-project" + ;; + libcxx) + echo "check-cxx" + ;; + libcxxabi) + echo "check-cxxabi" + ;; + libunwind) + echo "check-unwind" + ;; + lldb) + echo "check-lldb" + ;; + pstl) + # Currently we do not run pstl tests in CI. + ;; + libclc) + # Currently there is no testing for libclc. + ;; + *) + echo "check-${project}" + ;; + esac + done +} + diff --git a/.ci/generate-buildkite-pipeline-premerge b/.ci/generate-buildkite-pipeline-premerge index 190dd1e5ba5af..9d9ca32183944 100755 --- a/.ci/generate-buildkite-pipeline-premerge +++ b/.ci/generate-buildkite-pipeline-premerge @@ -52,184 +52,7 @@ modified_dirs=$(echo "$MODIFIED_FILES" | cut -d'/' -f1 | sort -u) echo "Directories modified:" >&2 echo "$modified_dirs" >&2 -function compute-projects-to-test() { - isForWindows=$1 - shift - projects=${@} - for project in ${projects}; do - echo "${project}" - case ${project} in - lld) - for p in bolt cross-project-tests; do - echo $p - done - ;; - llvm) - for p in bolt clang clang-tools-extra lld lldb mlir polly; do - echo $p - done - # Flang is not stable in Windows CI at the moment - if [[ $isForWindows == 0 ]]; then - echo flang - fi - ;; - clang) - # lldb is temporarily removed to alleviate Linux pre-commit CI waiting times - for p in clang-tools-extra compiler-rt cross-project-tests; do - echo $p - done - ;; - clang-tools-extra) - echo libc - ;; - mlir) - # Flang is not stable in Windows CI at the moment - if [[ $isForWindows == 0 ]]; then - echo flang - fi - ;; - *) - # Nothing to do - ;; - esac - done -} - -function compute-runtimes-to-test() { - projects=${@} - for project in ${projects}; do - case ${project} in - clang) - for p in libcxx libcxxabi libunwind; do - echo $p - done - ;; - *) - # Nothing to do - ;; - esac - done -} - -function add-dependencies() { - projects=${@} - for project in ${projects}; do - echo "${project}" - case ${project} in - bolt) - for p in clang lld llvm; do - echo $p - done - ;; - cross-project-tests) - for p in lld clang; do - echo $p - done - ;; - clang-tools-extra) - for p in llvm clang; do - echo $p - done - ;; - compiler-rt|libc|openmp) - echo clang lld - ;; - flang|lldb|libclc) - for p in llvm clang; do - echo $p - done - ;; - lld|mlir|polly) - echo llvm - ;; - *) - # Nothing to do - ;; - esac - done -} - -function exclude-linux() { - projects=${@} - for project in ${projects}; do - case ${project} in - cross-project-tests) ;; # tests failing - openmp) ;; # https://github.com/google/llvm-premerge-checks/issues/410 - *) - echo "${project}" - ;; - esac - done -} - -function exclude-windows() { - projects=${@} - for project in ${projects}; do - case ${project} in - cross-project-tests) ;; # tests failing - compiler-rt) ;; # tests taking too long - openmp) ;; # TODO: having trouble with the Perl installation - libc) ;; # no Windows support - lldb) ;; # custom environment requirements (https://github.com/llvm/llvm-project/pull/94208#issuecomment-2146256857) - bolt) ;; # tests are not supported yet - *) - echo "${project}" - ;; - esac - done -} - -# Prints only projects that are both present in $modified_dirs and the passed -# list. -function keep-modified-projects() { - projects=${@} - for project in ${projects}; do - if echo "$modified_dirs" | grep -q -E "^${project}$"; then - echo "${project}" - fi - done -} - -function check-targets() { - # Do not use "check-all" here because if there is "check-all" plus a - # project specific target like "check-clang", that project's tests - # will be run twice. - projects=${@} - for project in ${projects}; do - case ${project} in - clang-tools-extra) - echo "check-clang-tools" - ;; - compiler-rt) - echo "check-compiler-rt" - ;; - cross-project-tests) - echo "check-cross-project" - ;; - libcxx) - echo "check-cxx" - ;; - libcxxabi) - echo "check-cxxabi" - ;; - libunwind) - echo "check-unwind" - ;; - lldb) - echo "check-lldb" - ;; - pstl) - # Currently we do not run pstl tests in CI. - ;; - libclc) - # Currently there is no testing for libclc. - ;; - *) - echo "check-${project}" - ;; - esac - done -} +. ./.ci/compute-projects.sh # Project specific pipelines. diff --git a/.ci/generate_test_report.py b/.ci/generate_test_report.py index c44936b19dab9..ff601a0cde106 100644 --- a/.ci/generate_test_report.py +++ b/.ci/generate_test_report.py @@ -5,6 +5,7 @@ # python3 -m unittest discover -p generate_test_report.py import argparse +import os import subprocess import unittest from io import StringIO @@ -267,6 +268,46 @@ def test_report_dont_list_failures(self): ), ) + def test_report_dont_list_failures_link_to_log(self): + self.assertEqual( + _generate_report( + "Foo", + [ + junit_from_xml( + dedent( + """\ + + + + + + + + """ + ) + ) + ], + list_failures=False, + buildkite_info={ + "BUILDKITE_ORGANIZATION_SLUG": "organization_slug", + "BUILDKITE_PIPELINE_SLUG": "pipeline_slug", + "BUILDKITE_BUILD_NUMBER": "build_number", + "BUILDKITE_JOB_ID": "job_id", + }, + ), + ( + dedent( + """\ + # Foo + + * 1 test failed + + Failed tests and their output was too large to report. [Download](https://buildkite.com/organizations/organization_slug/pipelines/pipeline_slug/builds/build_number/jobs/job_id/download.txt) the build's log file to see the details.""" + ), + "error", + ), + ) + def test_report_size_limit(self): self.assertEqual( _generate_report( @@ -308,7 +349,13 @@ def test_report_size_limit(self): # listed. This minimal report will always fit into an annotation. # If include failures is False, total number of test will be reported but their names # and output will not be. -def _generate_report(title, junit_objects, size_limit=1024 * 1024, list_failures=True): +def _generate_report( + title, + junit_objects, + size_limit=1024 * 1024, + list_failures=True, + buildkite_info=None, +): if not junit_objects: return ("", "success") @@ -354,11 +401,21 @@ def plural(num_tests): report.append(f"* {tests_failed} {plural(tests_failed)} failed") if not list_failures: + if buildkite_info is not None: + log_url = ( + "https://buildkite.com/organizations/{BUILDKITE_ORGANIZATION_SLUG}/" + "pipelines/{BUILDKITE_PIPELINE_SLUG}/builds/{BUILDKITE_BUILD_NUMBER}/" + "jobs/{BUILDKITE_JOB_ID}/download.txt".format(**buildkite_info) + ) + download_text = f"[Download]({log_url})" + else: + download_text = "Download" + report.extend( [ "", "Failed tests and their output was too large to report. " - "Download the build's log file to see the details.", + f"{download_text} the build's log file to see the details.", ] ) elif failures: @@ -381,13 +438,23 @@ def plural(num_tests): report = "\n".join(report) if len(report.encode("utf-8")) > size_limit: - return _generate_report(title, junit_objects, size_limit, list_failures=False) + return _generate_report( + title, + junit_objects, + size_limit, + list_failures=False, + buildkite_info=buildkite_info, + ) return report, style -def generate_report(title, junit_files): - return _generate_report(title, [JUnitXml.fromfile(p) for p in junit_files]) +def generate_report(title, junit_files, buildkite_info): + return _generate_report( + title, + [JUnitXml.fromfile(p) for p in junit_files], + buildkite_info=buildkite_info, + ) if __name__ == "__main__": @@ -399,7 +466,18 @@ def generate_report(title, junit_files): parser.add_argument("junit_files", help="Paths to JUnit report files.", nargs="*") args = parser.parse_args() - report, style = generate_report(args.title, args.junit_files) + # All of these are required to build a link to download the log file. + env_var_names = [ + "BUILDKITE_ORGANIZATION_SLUG", + "BUILDKITE_PIPELINE_SLUG", + "BUILDKITE_BUILD_NUMBER", + "BUILDKITE_JOB_ID", + ] + buildkite_info = {k: v for k, v in os.environ.items() if k in env_var_names} + if len(buildkite_info) != len(env_var_names): + buildkite_info = None + + report, style = generate_report(args.title, args.junit_files, buildkite_info) if report: p = subprocess.Popen( diff --git a/.ci/monolithic-linux.sh b/.ci/monolithic-linux.sh index a4aeea7a16add..4bfebd5f75279 100755 --- a/.ci/monolithic-linux.sh +++ b/.ci/monolithic-linux.sh @@ -34,8 +34,11 @@ function at-exit { # If building fails there will be no results files. shopt -s nullglob - python3 "${MONOREPO_ROOT}"/.ci/generate_test_report.py ":linux: Linux x64 Test Results" \ - "linux-x64-test-results" "${BUILD_DIR}"/test-results.*.xml + if command -v buildkite-agent 2>&1 >/dev/null + then + python3 "${MONOREPO_ROOT}"/.ci/generate_test_report.py ":linux: Linux x64 Test Results" \ + "linux-x64-test-results" "${BUILD_DIR}"/test-results.*.xml + fi } trap at-exit EXIT diff --git a/.ci/monolithic-windows.sh b/.ci/monolithic-windows.sh index 4ead122212f4f..25cdd2f419f47 100755 --- a/.ci/monolithic-windows.sh +++ b/.ci/monolithic-windows.sh @@ -33,8 +33,11 @@ function at-exit { # If building fails there will be no results files. shopt -s nullglob - python "${MONOREPO_ROOT}"/.ci/generate_test_report.py ":windows: Windows x64 Test Results" \ - "windows-x64-test-results" "${BUILD_DIR}"/test-results.*.xml + if command -v buildkite-agent 2>&1 >/dev/null + then + python "${MONOREPO_ROOT}"/.ci/generate_test_report.py ":windows: Windows x64 Test Results" \ + "windows-x64-test-results" "${BUILD_DIR}"/test-results.*.xml + fi } trap at-exit EXIT diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 86be15b72fb64..9ef0713ef8af1 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -94,3 +94,6 @@ b6262880b34629e9d7a72b5a42f315a3c9ed8139 39c7dc7207e76e72da21cf4fedda21b5311bf62d e80bc777749331e9519575f416c342f7626dd14d 7e5cd8f1b6c5263ed5e2cc03d60c8779a8d3e9f7 + +# NFC: clang-format test_demangle.pass.cpp but keep test "lines" +d33bf2e9df578ff7e44fd22504d6ad5a122b7ee6 diff --git a/.github/workflows/build-ci-container-windows.yml b/.github/workflows/build-ci-container-windows.yml new file mode 100644 index 0000000000000..bba34066a97cd --- /dev/null +++ b/.github/workflows/build-ci-container-windows.yml @@ -0,0 +1,75 @@ +name: Build Windows CI Container + +permissions: + contents: read + +on: + push: + branches: + - main + paths: + - .github/workflows/build-ci-container-windows.yml + - '.github/workflows/containers/github-action-ci-windows/**' + pull_request: + branches: + - main + paths: + - .github/workflows/build-ci-container-windows.yml + - '.github/workflows/containers/github-action-ci-windows/**' + +jobs: + build-ci-container-windows: + if: github.repository_owner == 'llvm' + runs-on: windows-2019 + outputs: + container-name: ${{ steps.vars.outputs.container-name }} + container-name-tag: ${{ steps.vars.outputs.container-name-tag }} + container-filename: ${{ steps.vars.outputs.container-filename }} + steps: + - name: Checkout LLVM + uses: actions/checkout@v4 + with: + sparse-checkout: .github/workflows/containers/github-action-ci-windows + - name: Write Variables + id: vars + run: | + $tag = [int64](Get-Date -UFormat %s) + $container_name="ghcr.io/$env:GITHUB_REPOSITORY_OWNER/ci-windows-2019" + echo "container-name=${container_name}" >> $env:GITHUB_OUTPUT + echo "container-name-tag=${container_name}:${tag}" >> $env:GITHUB_OUTPUT + echo "container-filename=ci-windows-${tag}.tar" >> $env:GITHUB_OUTPUT + - name: Build Container + working-directory: .github/workflows/containers/github-action-ci-windows + run: | + docker build -t ${{ steps.vars.outputs.container-name-tag }} . + - name: Save container image + run: | + docker save ${{ steps.vars.outputs.container-name-tag }} > ${{ steps.vars.outputs.container-filename }} + - name: Upload container image + uses: actions/upload-artifact@v4 + with: + name: container + path: ${{ steps.vars.outputs.container-filename }} + retention-days: 14 + + push-ci-container: + if: github.event_name == 'push' + needs: + - build-ci-container-windows + permissions: + packages: write + runs-on: windows-2019 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Download container + uses: actions/download-artifact@v4 + with: + name: container + - name: Push Container + run: | + docker load -i ${{ needs.build-ci-container-windows.outputs.container-filename }} + docker tag ${{ needs.build-ci-container-windows.outputs.container-name-tag }} ${{ needs.build-ci-container-windows.outputs.container-name }}:latest + docker login -u ${{ github.actor }} -p $env:GITHUB_TOKEN ghcr.io + docker push ${{ needs.build-ci-container-windows.outputs.container-name-tag }} + docker push ${{ needs.build-ci-container-windows.outputs.container-name }}:latest diff --git a/.github/workflows/build-ci-container.yml b/.github/workflows/build-ci-container.yml index 28fc7de2ee065..50729e0173506 100644 --- a/.github/workflows/build-ci-container.yml +++ b/.github/workflows/build-ci-container.yml @@ -18,44 +18,18 @@ on: - '.github/workflows/containers/github-action-ci/**' jobs: - # TODO(boomanaiden154): Switch this back to a single stage build when we can - # run this on the self-hosted runners and don't have to do it this way to - # avoid timeouts. - build-ci-container-stage1: + build-ci-container: if: github.repository_owner == 'llvm' - runs-on: ubuntu-latest + runs-on: depot-ubuntu-22.04-16 + outputs: + container-name: ${{ steps.vars.outputs.container-name }} + container-name-tag: ${{ steps.vars.outputs.container-name-tag }} + container-filename: ${{ steps.vars.outputs.container-filename }} steps: - name: Checkout LLVM uses: actions/checkout@v4 with: sparse-checkout: .github/workflows/containers/github-action-ci/ - - name: Change podman Root Direcotry - run: | - mkdir -p ~/.config/containers - sudo mkdir -p /mnt/podman - sudo chown `whoami`:`whoami` /mnt/podman - cp ./.github/workflows/containers/github-action-ci/storage.conf ~/.config/containers/storage.conf - podman info - - name: Build container stage1 - working-directory: ./.github/workflows/containers/github-action-ci/ - run: | - podman build -t stage1-toolchain --target stage1-toolchain -f stage1.Dockerfile . - - name: Save container image - run: | - podman save stage1-toolchain > stage1-toolchain.tar - - name: Upload container image - uses: actions/upload-artifact@v4 - with: - name: stage1-toolchain - path: stage1-toolchain.tar - retention-days: 1 - build-ci-container-stage2: - if: github.repository_owner == 'llvm' - runs-on: ubuntu-latest - needs: build-ci-container-stage1 - permissions: - packages: write - steps: - name: Write Variables id: vars run: | @@ -63,50 +37,51 @@ jobs: container_name="ghcr.io/$GITHUB_REPOSITORY_OWNER/ci-ubuntu-22.04" echo "container-name=$container_name" >> $GITHUB_OUTPUT echo "container-name-tag=$container_name:$tag" >> $GITHUB_OUTPUT - - - name: Checkout LLVM - uses: actions/checkout@v4 - with: - sparse-checkout: .github/workflows/containers/github-action-ci/ - - - name: Change podman Root Direcotry + echo "container-filename=$(echo $container_name:$tag | sed -e 's/\//-/g' -e 's/:/-/g').tar" >> $GITHUB_OUTPUT + - name: Build container + working-directory: ./.github/workflows/containers/github-action-ci/ run: | - mkdir -p ~/.config/containers - sudo mkdir -p /mnt/podman - sudo chown `whoami`:`whoami` /mnt/podman - cp ./.github/workflows/containers/github-action-ci/storage.conf ~/.config/containers/storage.conf - podman info - - # Download the container image into /mnt/podman rather than - # $GITHUB_WORKSPACE to avoid space limitations on the default drive - # and use the permissions setup for /mnt/podman. - - name: Download stage1-toolchain - uses: actions/download-artifact@v4 - with: - name: stage1-toolchain - path: /mnt/podman + podman build -t ${{ steps.vars.outputs.container-name-tag }} . - - name: Load stage1-toolchain + # Save the container so we have it in case the push fails. This also + # allows us to separate the push step into a different job so we can + # maintain minimal permissions while building the container. + - name: Save container image run: | - podman load -i /mnt/podman/stage1-toolchain.tar + podman save ${{ steps.vars.outputs.container-name-tag }} > ${{ steps.vars.outputs.container-filename }} - - name: Build Container - working-directory: ./.github/workflows/containers/github-action-ci/ - run: | - podman build -t ${{ steps.vars.outputs.container-name-tag }} -f stage2.Dockerfile . - podman tag ${{ steps.vars.outputs.container-name-tag }} ${{ steps.vars.outputs.container-name }}:latest + - name: Upload container image + uses: actions/upload-artifact@v4 + with: + name: container + path: ${{ steps.vars.outputs.container-filename }} + retention-days: 14 - name: Test Container run: | for image in ${{ steps.vars.outputs.container-name-tag }} ${{ steps.vars.outputs.container-name }}; do - podman run --rm -it $image /usr/bin/bash -x -c 'printf '\''#include \nint main(int argc, char **argv) { std::cout << "Hello\\n"; }'\'' | clang++ -x c++ - && ./a.out | grep Hello' + podman run --rm -it $image /usr/bin/bash -x -c 'cd $HOME && printf '\''#include \nint main(int argc, char **argv) { std::cout << "Hello\\n"; }'\'' | clang++ -x c++ - && ./a.out | grep Hello' done + push-ci-container: + if: github.event_name == 'push' + needs: + - build-ci-container + permissions: + packages: write + runs-on: ubuntu-24.04 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Download container + uses: actions/download-artifact@v4 + with: + name: container + - name: Push Container - if: github.event_name == 'push' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | + podman load -i ${{ needs.build-ci-container.outputs.container-filename }} + podman tag ${{ needs.build-ci-container.outputs.container-name-tag }} ${{ needs.build-ci-container.outputs.container-name }}:latest podman login -u ${{ github.actor }} -p $GITHUB_TOKEN ghcr.io - podman push ${{ steps.vars.outputs.container-name-tag }} - podman push ${{ steps.vars.outputs.container-name }}:latest + podman push ${{ needs.build-ci-container.outputs.container-name-tag }} + podman push ${{ needs.build-ci-container.outputs.container-name }}:latest diff --git a/.github/workflows/commit-access-review.py b/.github/workflows/commit-access-review.py index 8ea9b1fcc2fb0..91d3a61cdcb17 100644 --- a/.github/workflows/commit-access-review.py +++ b/.github/workflows/commit-access-review.py @@ -62,57 +62,9 @@ def __repr__(self): ) -def run_graphql_query( - query: str, variables: dict, token: str, retry: bool = True -) -> dict: - """ - This function submits a graphql query and returns the results as a - dictionary. - """ - s = requests.Session() - retries = requests.adapters.Retry(total=8, backoff_factor=2, status_forcelist=[504]) - s.mount("https://", requests.adapters.HTTPAdapter(max_retries=retries)) - - headers = { - "Authorization": "bearer {}".format(token), - # See - # https://github.blog/2021-11-16-graphql-global-id-migration-update/ - "X-Github-Next-Global-ID": "1", - } - request = s.post( - url="https://api.github.com/graphql", - json={"query": query, "variables": variables}, - headers=headers, - ) - - rate_limit = request.headers.get("X-RateLimit-Remaining") - print(rate_limit) - if rate_limit and int(rate_limit) < 10: - reset_time = int(request.headers["X-RateLimit-Reset"]) - while reset_time - int(time.time()) > 0: - time.sleep(60) - print( - "Waiting until rate limit reset", - reset_time - int(time.time()), - "seconds remaining", - ) - - if request.status_code == 200: - if "data" not in request.json(): - print(request.json()) - sys.exit(1) - return request.json()["data"] - elif retry: - return run_graphql_query(query, variables, token, False) - else: - raise Exception( - "Failed to run graphql query\nquery: {}\nerror: {}".format( - query, request.json() - ) - ) - - -def check_manual_requests(start_date: datetime.datetime, token: str) -> list[str]: +def check_manual_requests( + gh: github.Github, start_date: datetime.datetime +) -> list[str]: """ Return a list of users who have been asked since ``start_date`` if they want to keep their commit access. @@ -137,10 +89,13 @@ def check_manual_requests(start_date: datetime.datetime, token: str) -> list[str """ formatted_start_date = start_date.strftime("%Y-%m-%dT%H:%M:%S") variables = { - "query": f"type:issue created:>{formatted_start_date} org:llvm repo:llvm-project label:infrastructure:commit-access" + "query": f"type:issue created:>{formatted_start_date} org:llvm repo:llvm-project label:infra:commit-access" } - data = run_graphql_query(query, variables, token) + res_header, res_data = gh._Github__requester.graphql_query( + query=query, variables=variables + ) + data = res_data["data"] users = [] for issue in data["search"]["nodes"]: users.extend([user[1:] for user in re.findall("@[^ ,\n]+", issue["body"])]) @@ -148,7 +103,7 @@ def check_manual_requests(start_date: datetime.datetime, token: str) -> list[str return users -def get_num_commits(user: str, start_date: datetime.datetime, token: str) -> int: +def get_num_commits(gh: github.Github, user: str, start_date: datetime.datetime) -> int: """ Get number of commits that ``user`` has been made since ``start_date`. """ @@ -166,7 +121,10 @@ def get_num_commits(user: str, start_date: datetime.datetime, token: str) -> int } """ - data = run_graphql_query(user_query, variables, token) + res_header, res_data = gh._Github__requester.graphql_query( + query=user_query, variables=variables + ) + data = res_data["data"] variables["user_id"] = data["user"]["id"] query = """ @@ -193,7 +151,10 @@ def get_num_commits(user: str, start_date: datetime.datetime, token: str) -> int } """ count = 0 - data = run_graphql_query(query, variables, token) + res_header, res_data = gh._Github__requester.graphql_query( + query=query, variables=variables + ) + data = res_data["data"] for repo in data["organization"]["teams"]["nodes"][0]["repositories"]["nodes"]: count += int(repo["ref"]["target"]["history"]["totalCount"]) if count >= User.THRESHOLD: @@ -202,7 +163,7 @@ def get_num_commits(user: str, start_date: datetime.datetime, token: str) -> int def is_new_committer_query_repo( - user: str, start_date: datetime.datetime, token: str + gh: github.Github, user: str, start_date: datetime.datetime ) -> bool: """ Determine if ``user`` is a new committer. A new committer can keep their @@ -220,7 +181,10 @@ def is_new_committer_query_repo( } """ - data = run_graphql_query(user_query, variables, token) + res_header, res_data = gh._Github__requester.graphql_query( + query=user_query, variables=variables + ) + data = res_data["data"] variables["owner"] = "llvm" variables["user_id"] = data["user"]["id"] variables["start_date"] = start_date.strftime("%Y-%m-%dT%H:%M:%S") @@ -245,7 +209,10 @@ def is_new_committer_query_repo( } """ - data = run_graphql_query(query, variables, token) + res_header, res_data = gh._Github__requester.graphql_query( + query=query, variables=variables + ) + data = res_data["data"] repo = data["organization"]["repository"] commits = repo["ref"]["target"]["history"]["nodes"] if len(commits) == 0: @@ -256,18 +223,22 @@ def is_new_committer_query_repo( return True -def is_new_committer(user: str, start_date: datetime.datetime, token: str) -> bool: +def is_new_committer( + gh: github.Github, user: str, start_date: datetime.datetime +) -> bool: """ Wrapper around is_new_commiter_query_repo to handle exceptions. """ try: - return is_new_committer_query_repo(user, start_date, token) + return is_new_committer_query_repo(gh, user, start_date) except: pass return True -def get_review_count(user: str, start_date: datetime.datetime, token: str) -> int: +def get_review_count( + gh: github.Github, user: str, start_date: datetime.datetime +) -> int: """ Return the number of reviews that ``user`` has done since ``start_date``. """ @@ -286,11 +257,14 @@ def get_review_count(user: str, start_date: datetime.datetime, token: str) -> in "query": f"type:pr commenter:{user} -author:{user} merged:>{formatted_start_date} org:llvm", } - data = run_graphql_query(query, variables, token) + res_header, res_data = gh._Github__requester.graphql_query( + query=query, variables=variables + ) + data = res_data["data"] return int(data["search"]["issueCount"]) -def count_prs(triage_list: dict, start_date: datetime.datetime, token: str): +def count_prs(gh: github.Github, triage_list: dict, start_date: datetime.datetime): """ Fetch all the merged PRs for the project since ``start_date`` and update ``triage_list`` with the number of PRs merged for each user. @@ -329,7 +303,10 @@ def count_prs(triage_list: dict, start_date: datetime.datetime, token: str): has_next_page = True while has_next_page: print(variables) - data = run_graphql_query(query, variables, token) + res_header, res_data = gh._Github__requester.graphql_query( + query=query, variables=variables + ) + data = res_data["data"] for pr in data["search"]["nodes"]: # Users can be None if the user has been deleted. if not pr["author"]: @@ -365,14 +342,14 @@ def main(): print("Start:", len(triage_list), "triagers") # Step 0 Check if users have requested commit access in the last year. - for user in check_manual_requests(one_year_ago, token): + for user in check_manual_requests(gh, one_year_ago): if user in triage_list: print(user, "requested commit access in the last year.") del triage_list[user] print("After Request Check:", len(triage_list), "triagers") # Step 1 count all PRs authored or merged - count_prs(triage_list, one_year_ago, token) + count_prs(gh, triage_list, one_year_ago) print("After PRs:", len(triage_list), "triagers") @@ -381,7 +358,7 @@ def main(): # Step 2 check for reviews for user in list(triage_list.keys()): - review_count = get_review_count(user, one_year_ago, token) + review_count = get_review_count(gh, user, one_year_ago) triage_list[user].add_reviewed(review_count) print("After Reviews:", len(triage_list), "triagers") @@ -391,7 +368,7 @@ def main(): # Step 3 check for number of commits for user in list(triage_list.keys()): - num_commits = get_num_commits(user, one_year_ago, token) + num_commits = get_num_commits(gh, user, one_year_ago) # Override the total number of commits to not double count commits and # authored PRs. triage_list[user].set_authored(num_commits) @@ -401,7 +378,7 @@ def main(): # Step 4 check for new committers for user in list(triage_list.keys()): print("Checking", user) - if is_new_committer(user, one_year_ago, token): + if is_new_committer(gh, user, one_year_ago): print("Removing new committer: ", user) del triage_list[user] diff --git a/.github/workflows/containers/github-action-ci-windows/Dockerfile b/.github/workflows/containers/github-action-ci-windows/Dockerfile new file mode 100644 index 0000000000000..bc56e20935500 --- /dev/null +++ b/.github/workflows/containers/github-action-ci-windows/Dockerfile @@ -0,0 +1,118 @@ +# Agent image for LLVM org cluster. +# .net 4.8 is required by chocolately package manager. +FROM mcr.microsoft.com/dotnet/framework/sdk:4.8-windowsservercore-ltsc2019 + +# Restore the default Windows shell for correct batch processing. +SHELL ["cmd", "/S", "/C"] + +# Download the Build Tools bootstrapper. +ADD https://aka.ms/vs/16/release/vs_buildtools.exe /TEMP/vs_buildtools.exe + +RUN powershell -Command Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) + +# Download channel for fixed install. +ARG CHANNEL_URL=https://aka.ms/vs/16/release/channel +ADD ${CHANNEL_URL} /TEMP/VisualStudio.chman + +# Install Build Tools with C++ workload. +# - Documentation for docker installation +# https://docs.microsoft.com/en-us/visualstudio/install/build-tools-container?view=vs-2019 +# - Documentation on workloads +# https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-build-tools?view=vs-2019#c-build-tools +# - Documentation on flags +# https://docs.microsoft.com/en-us/visualstudio/install/use-command-line-parameters-to-install-visual-studio?view=vs-2019 +RUN /TEMP/vs_buildtools.exe --quiet --wait --norestart --nocache \ + --channelUri C:\TEMP\VisualStudio.chman \ + --installChannelUri C:\TEMP\VisualStudio.chman \ + --installPath C:\BuildTools \ + --add Microsoft.VisualStudio.Workload.VCTools \ + --add Microsoft.VisualStudio.Component.VC.ATL \ + --includeRecommended \ + || IF "%ERRORLEVEL%"=="3010" EXIT 0 + +# Register DIA dll (Debug Interface Access) so it can be used to symbolize +# the stack traces. Register dll for 32 and 64 bit. +# see https://developercommunity.visualstudio.com/content/problem/290674/msdia140dll-is-not-registered-on-vs2017-hosts.html + +RUN regsvr32 /S "C:\BuildTools\DIA SDK\bin\amd64\msdia140.dll" & \ + regsvr32 /S "C:\BuildTools\DIA SDK\bin\msdia140.dll" + +# install tools as described in https://llvm.org/docs/GettingStartedVS.html +# and a few more that were not documented... +RUN choco install -y ninja git +# Pin an older version of Python; the current Python 3.10 fails when +# doing "pip install" for the other dependencies, as it fails to find libxml +# while compiling some package. +RUN choco install -y python3 --version 3.9.7 + +# ActivePerl is currently not installable via Chocolatey, see +# http://disq.us/p/2ipditb. Install StrawberryPerl instead. Unfortunately, +# StrawberryPerl not only installs Perl, but also a redundant C/C++ compiler +# toolchain, and a copy of pkg-config which can cause misdetections for other +# built products, see +# https://github.com/StrawberryPerl/Perl-Dist-Strawberry/issues/11 for further +# details. Remove the redundant and unnecessary parts of the StrawberryPerl +# install. +RUN choco install -y strawberryperl && \ + rmdir /q /s c:\strawberry\c && \ + del /q c:\strawberry\perl\bin\pkg-config* + +# libcxx requires clang(-cl) to be available +RUN choco install -y sccache llvm +RUN pip install psutil + +RUN curl -LO https://github.com/mstorsjo/llvm-mingw/releases/download/20230320/llvm-mingw-20230320-ucrt-x86_64.zip && \ + powershell Expand-Archive llvm-mingw-*-ucrt-x86_64.zip -DestinationPath . && \ + del llvm-mingw-*-ucrt-x86_64.zip && \ + ren llvm-mingw-20230320-ucrt-x86_64 llvm-mingw + +# configure Python encoding +ENV PYTHONIOENCODING=UTF-8 + +# update the path variable +# C:\Program Files\Git\usr\bin contains a usable bash and other unix tools. +# C:\llvm-mingw\bin contains Clang configured for mingw targets and +# corresponding sysroots. Both the 'llvm' package (with Clang defaulting +# to MSVC targets) and this directory contains executables named +# 'clang.exe' - add this last to let the other one have precedence. +# To use these compilers, use the triple prefixed form, e.g. +# x86_64-w64-mingw32-clang. +# C:\buildtools and SDK paths are ones that are set by c:\BuildTools\Common7\Tools\VsDevCmd.bat -arch=amd64 -host_arch=amd64 +RUN powershell -Command \ + [System.Environment]::SetEnvironmentVariable('PATH', \ + [System.Environment]::GetEnvironmentVariable('PATH', 'machine') + ';C:\Program Files\Git\usr\bin;C:\llvm-mingw\bin' \ + + ';C:\BuildTools\Common7\IDE\' \ + + ';C:\BuildTools\Common7\IDE\CommonExt ensions\Microsoft\TeamFoundation\Team Explorer' \ + + ';C:\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin' \ + + ';C:\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja' \ + + ';C:\BuildTools\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer' \ + + ';C:\BuildTools\Common7\IDE\CommonExtensions\Microsoft\TestWindow' \ + + ';C:\BuildTools\Common7\IDE\VC\VCPackages' \ + + ';C:\BuildTools\Common7\Tools\' \ + + ';C:\BuildTools\Common7\Tools\devinit' \ + + ';C:\BuildTools\MSBuild\Current\Bin' \ + + ';C:\BuildTools\MSBuild\Current\bin\Roslyn' \ + + ';C:\BuildTools\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64' \ + + ';C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\x64\' \ + + ';C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64' \ + + ';C:\Program Files (x86)\Windows Kits\10\bin\x64' \ + + ';C:\Windows\Microsoft.NET\Framework64\v4.0.30319' \ + ,'machine') + +# support long file names during git checkout +RUN git config --system core.longpaths true & \ + git config --global core.autocrlf false + +# handle for debugging of files beeing locked by some processes. +RUN choco install -y handle + +RUN pip3 install pywin32 buildbot-worker==2.8.4 + +ARG RUNNER_VERSION=2.319.1 +ENV RUNNER_VERSION=$RUNNER_VERSION + +RUN powershell -Command \ + Invoke-WebRequest -Uri https://github.com/actions/runner/releases/download/v${env:RUNNER_VERSION}/actions-runner-win-x64-${env:RUNNER_VERSION}.zip -OutFile actions-runner-win.zip ; \ + Add-Type -AssemblyName System.IO.Compression.FileSystem ; \ + [System.IO.Compression.ZipFile]::ExtractToDirectory('actions-runner-win.zip', $PWD) ;\ + rm actions-runner-win.zip diff --git a/.github/workflows/containers/github-action-ci/Dockerfile b/.github/workflows/containers/github-action-ci/Dockerfile new file mode 100644 index 0000000000000..58355d261c43c --- /dev/null +++ b/.github/workflows/containers/github-action-ci/Dockerfile @@ -0,0 +1,77 @@ +FROM docker.io/library/ubuntu:22.04 as base +ENV LLVM_SYSROOT=/opt/llvm + +FROM base as stage1-toolchain +ENV LLVM_VERSION=19.1.5 + +RUN apt-get update && \ + apt-get install -y \ + wget \ + gcc \ + g++ \ + cmake \ + ninja-build \ + python3 \ + git \ + curl + +RUN curl -O -L https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-$LLVM_VERSION.tar.gz && tar -xf llvmorg-$LLVM_VERSION.tar.gz + +WORKDIR /llvm-project-llvmorg-$LLVM_VERSION + +# Patch to enable better PGO profile data. +# TODO: Remove this for llvm 20 +ADD https://github.com/llvm/llvm-project/commit/738250989ce516f02f809bdfde474a039c77e81f.patch . + +RUN patch -p1 < 738250989ce516f02f809bdfde474a039c77e81f.patch + +RUN cmake -B ./build -G Ninja ./llvm \ + -C ./clang/cmake/caches/BOLT-PGO.cmake \ + -DBOOTSTRAP_LLVM_ENABLE_LLD=ON \ + -DBOOTSTRAP_BOOTSTRAP_LLVM_ENABLE_LLD=ON \ + -DPGO_INSTRUMENT_LTO=Thin \ + -DLLVM_ENABLE_RUNTIMES="compiler-rt" \ + -DCMAKE_INSTALL_PREFIX="$LLVM_SYSROOT" \ + -DLLVM_ENABLE_PROJECTS="bolt;clang;lld;clang-tools-extra" \ + -DLLVM_DISTRIBUTION_COMPONENTS="lld;compiler-rt;clang-format;scan-build" \ + -DCLANG_DEFAULT_LINKER="lld" + +RUN ninja -C ./build stage2-clang-bolt stage2-install-distribution && ninja -C ./build install-distribution + +FROM base + +COPY --from=stage1-toolchain $LLVM_SYSROOT $LLVM_SYSROOT + +# Need to install curl for hendrikmuhs/ccache-action +# Need nodejs for some of the GitHub actions. +# Need perl-modules for clang analyzer tests. +# Need git for SPIRV-Tools tests. +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + binutils \ + cmake \ + curl \ + git \ + libstdc++-11-dev \ + ninja-build \ + nodejs \ + perl-modules \ + python3-psutil \ + + # These are needed by the premerge pipeline. Pip is used to install + # dependent python packages and ccache is used for build caching. File and + # tzdata are used for tests. + python3-pip \ + ccache \ + file \ + tzdata + +ENV LLVM_SYSROOT=$LLVM_SYSROOT +ENV PATH=${LLVM_SYSROOT}/bin:${PATH} + +# Create a new user to avoid test failures related to a lack of expected +# permissions issues in some tests. Set the user id to 1001 as that is the +# user id that Github Actions uses to perform the checkout action. +RUN useradd gha -u 1001 -m -s /bin/bash +USER gha + diff --git a/.github/workflows/containers/github-action-ci/bootstrap.patch b/.github/workflows/containers/github-action-ci/bootstrap.patch deleted file mode 100644 index 55631c54a396f..0000000000000 --- a/.github/workflows/containers/github-action-ci/bootstrap.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/clang/cmake/caches/BOLT-PGO.cmake b/clang/cmake/caches/BOLT-PGO.cmake -index 1a04ca9a74e5..d092820e4115 100644 ---- a/clang/cmake/caches/BOLT-PGO.cmake -+++ b/clang/cmake/caches/BOLT-PGO.cmake -@@ -4,6 +4,8 @@ set(CLANG_BOOTSTRAP_TARGETS - stage2-clang-bolt - stage2-distribution - stage2-install-distribution -+ clang -+ lld - CACHE STRING "") - set(BOOTSTRAP_CLANG_BOOTSTRAP_TARGETS - clang-bolt diff --git a/.github/workflows/containers/github-action-ci/stage1.Dockerfile b/.github/workflows/containers/github-action-ci/stage1.Dockerfile deleted file mode 100644 index 3e2c1ab11d58b..0000000000000 --- a/.github/workflows/containers/github-action-ci/stage1.Dockerfile +++ /dev/null @@ -1,42 +0,0 @@ -FROM docker.io/library/ubuntu:22.04 as base -ENV LLVM_SYSROOT=/opt/llvm - -FROM base as stage1-toolchain -ENV LLVM_VERSION=19.1.2 - -RUN apt-get update && \ - apt-get install -y \ - wget \ - gcc \ - g++ \ - cmake \ - ninja-build \ - python3 \ - git \ - curl - -RUN curl -O -L https://github.com/llvm/llvm-project/archive/refs/tags/llvmorg-$LLVM_VERSION.tar.gz && tar -xf llvmorg-$LLVM_VERSION.tar.gz - -WORKDIR /llvm-project-llvmorg-$LLVM_VERSION - -COPY bootstrap.patch / - -# TODO(boomanaiden154): Remove the bootstrap patch once we unsplit the build -# and no longer need to explicitly build the stage2 dependencies. -RUN cat /bootstrap.patch | patch -p1 - -RUN mkdir build - -RUN cmake -B ./build -G Ninja ./llvm \ - -C ./clang/cmake/caches/BOLT-PGO.cmake \ - -DBOOTSTRAP_LLVM_ENABLE_LLD=ON \ - -DBOOTSTRAP_BOOTSTRAP_LLVM_ENABLE_LLD=ON \ - -DPGO_INSTRUMENT_LTO=Thin \ - -DLLVM_ENABLE_RUNTIMES="compiler-rt" \ - -DCMAKE_INSTALL_PREFIX="$LLVM_SYSROOT" \ - -DLLVM_ENABLE_PROJECTS="bolt;clang;lld;clang-tools-extra" \ - -DLLVM_DISTRIBUTION_COMPONENTS="lld;compiler-rt;clang-format;scan-build" \ - -DCLANG_DEFAULT_LINKER="lld" \ - -DBOOTSTRAP_CLANG_PGO_TRAINING_DATA_SOURCE_DIR=/llvm-project-llvmorg-$LLVM_VERSION/llvm - -RUN ninja -C ./build stage2-instrumented-clang stage2-instrumented-lld diff --git a/.github/workflows/containers/github-action-ci/stage2.Dockerfile b/.github/workflows/containers/github-action-ci/stage2.Dockerfile deleted file mode 100644 index 0ca0da87734c4..0000000000000 --- a/.github/workflows/containers/github-action-ci/stage2.Dockerfile +++ /dev/null @@ -1,29 +0,0 @@ -FROM docker.io/library/ubuntu:22.04 as base -ENV LLVM_SYSROOT=/opt/llvm - -FROM stage1-toolchain AS stage2-toolchain - -RUN ninja -C ./build stage2-clang-bolt stage2-install-distribution && ninja -C ./build install-distribution && rm -rf ./build - -FROM base - -COPY --from=stage2-toolchain $LLVM_SYSROOT $LLVM_SYSROOT - -# Need to install curl for hendrikmuhs/ccache-action -# Need nodejs for some of the GitHub actions. -# Need perl-modules for clang analyzer tests. -# Need git for SPIRV-Tools tests. -RUN apt-get update && \ - apt-get install -y \ - binutils \ - cmake \ - curl \ - git \ - libstdc++-11-dev \ - ninja-build \ - nodejs \ - perl-modules \ - python3-psutil - -ENV LLVM_SYSROOT=$LLVM_SYSROOT -ENV PATH=${LLVM_SYSROOT}/bin:${PATH} diff --git a/.github/workflows/containers/github-action-ci/storage.conf b/.github/workflows/containers/github-action-ci/storage.conf deleted file mode 100644 index 60f295ff1e969..0000000000000 --- a/.github/workflows/containers/github-action-ci/storage.conf +++ /dev/null @@ -1,4 +0,0 @@ -[storage] - driver = "overlay" - runroot = "/mnt/podman/container" - graphroot = "/mnt/podman/image" diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 0bb018b780a2a..8441589bb716e 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -94,6 +94,8 @@ jobs: flang: - 'flang/docs/**' - 'flang/include/flang/Optimizer/Dialect/FIROps.td' + workflow: + - '.github/workflows/docs.yml' - name: Fetch LLVM sources (PR) if: ${{ github.event_name == 'pull_request' }} uses: actions/checkout@v4 @@ -115,77 +117,99 @@ jobs: - name: Setup output folder run: mkdir built-docs - name: Build LLVM docs - if: steps.docs-changed-subprojects.outputs.llvm_any_changed == 'true' + if: | + steps.docs-changed-subprojects.outputs.llvm_any_changed == 'true' || + steps.docs-changed-subprojects.outputs.workflow_any_changed == 'true' run: | cmake -B llvm-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_SPHINX=ON ./llvm TZ=UTC ninja -C llvm-build docs-llvm-html docs-llvm-man mkdir built-docs/llvm cp -r llvm-build/docs/* built-docs/llvm/ - name: Build Clang docs - if: steps.docs-changed-subprojects.outputs.clang_any_changed == 'true' + if: | + steps.docs-changed-subprojects.outputs.clang_any_changed == 'true' || + steps.docs-changed-subprojects.outputs.workflow_any_changed == 'true' run: | cmake -B clang-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_SPHINX=ON ./llvm TZ=UTC ninja -C clang-build docs-clang-html docs-clang-man mkdir built-docs/clang cp -r clang-build/docs/* built-docs/clang/ - name: Build clang-tools-extra docs - if: steps.docs-changed-subprojects.outputs.clang-tools-extra_any_changed == 'true' + if: | + steps.docs-changed-subprojects.outputs.clang-tools-extra_any_changed == 'true' || + steps.docs-changed-subprojects.outputs.workflow_any_changed == 'true' run: | cmake -B clang-tools-extra-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" -DLLVM_ENABLE_SPHINX=ON ./llvm TZ=UTC ninja -C clang-tools-extra-build docs-clang-tools-html docs-clang-tools-man mkdir built-docs/clang-tools-extra cp -r clang-tools-extra-build/docs/* built-docs/clang-tools-extra/ - name: Build LLDB docs - if: steps.docs-changed-subprojects.outputs.lldb_any_changed == 'true' + if: | + steps.docs-changed-subprojects.outputs.lldb_any_changed == 'true' || + steps.docs-changed-subprojects.outputs.workflow_any_changed == 'true' run: | cmake -B lldb-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;lldb" -DLLVM_ENABLE_SPHINX=ON ./llvm TZ=UTC ninja -C lldb-build docs-lldb-html docs-lldb-man mkdir built-docs/lldb cp -r lldb-build/docs/* built-docs/lldb/ - name: Build libunwind docs - if: steps.docs-changed-subprojects.outputs.libunwind_any_changed == 'true' + if: | + steps.docs-changed-subprojects.outputs.libunwind_any_changed == 'true' || + steps.docs-changed-subprojects.outputs.workflow_any_changed == 'true' run: | cmake -B libunwind-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_RUNTIMES="libunwind" -DLLVM_ENABLE_SPHINX=ON ./runtimes TZ=UTC ninja -C libunwind-build docs-libunwind-html mkdir built-docs/libunwind cp -r libunwind-build/libunwind/docs/* built-docs/libunwind - name: Build libcxx docs - if: steps.docs-changed-subprojects.outputs.libcxx_any_changed == 'true' + if: | + steps.docs-changed-subprojects.outputs.libcxx_any_changed == 'true' || + steps.docs-changed-subprojects.outputs.workflow_any_changed == 'true' run: | cmake -B libcxx-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_RUNTIMES="libcxxabi;libcxx;libunwind" -DLLVM_ENABLE_SPHINX=ON ./runtimes TZ=UTC ninja -C libcxx-build docs-libcxx-html mkdir built-docs/libcxx cp -r libcxx-build/libcxx/docs/* built-docs/libcxx/ - name: Build libc docs - if: steps.docs-changed-subprojects.outputs.libc_any_changed == 'true' + if: | + steps.docs-changed-subprojects.outputs.libc_any_changed == 'true' || + steps.docs-changed-subprojects.outputs.workflow_any_changed == 'true' run: | cmake -B libc-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_RUNTIMES="libc" -DLLVM_ENABLE_SPHINX=ON ./runtimes TZ=UTC ninja -C libc-build docs-libc-html mkdir built-docs/libc cp -r libc-build/libc/docs/* built-docs/libc/ - name: Build LLD docs - if: steps.docs-changed-subprojects.outputs.lld_any_changed == 'true' + if: | + steps.docs-changed-subprojects.outputs.lld_any_changed == 'true' || + steps.docs-changed-subprojects.outputs.workflow_any_changed == 'true' run: | cmake -B lld-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="lld" -DLLVM_ENABLE_SPHINX=ON ./llvm TZ=UTC ninja -C lld-build docs-lld-html mkdir built-docs/lld cp -r lld-build/docs/* built-docs/lld/ - name: Build OpenMP docs - if: steps.docs-changed-subprojects.outputs.openmp_any_changed == 'true' + if: | + steps.docs-changed-subprojects.outputs.openmp_any_changed == 'true' || + steps.docs-changed-subprojects.outputs.workflow_any_changed == 'true' run: | cmake -B openmp-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;openmp" -DLLVM_ENABLE_SPHINX=ON ./llvm TZ=UTC ninja -C openmp-build docs-openmp-html mkdir built-docs/openmp cp -r openmp-build/docs/* built-docs/openmp/ - name: Build Polly docs - if: steps.docs-changed-subprojects.outputs.polly_any_changed == 'true' + if: | + steps.docs-changed-subprojects.outputs.polly_any_changed == 'true' || + steps.docs-changed-subprojects.outputs.workflow_any_changed == 'true' run: | cmake -B polly-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="polly" -DLLVM_ENABLE_SPHINX=ON ./llvm TZ=UTC ninja -C polly-build docs-polly-html docs-polly-man mkdir built-docs/polly cp -r polly-build/docs/* built-docs/polly/ - name: Build Flang docs - if: steps.docs-changed-subprojects.outputs.flang_any_changed == 'true' + if: | + steps.docs-changed-subprojects.outputs.flang_any_changed == 'true' || + steps.docs-changed-subprojects.outputs.workflow_any_changed == 'true' run: | cmake -B flang-build -GNinja -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_PROJECTS="clang;mlir;flang" -DLLVM_ENABLE_SPHINX=ON ./llvm TZ=UTC ninja -C flang-build docs-flang-html diff --git a/.github/workflows/libc-fullbuild-tests.yml b/.github/workflows/libc-fullbuild-tests.yml new file mode 100644 index 0000000000000..58e15ce29546e --- /dev/null +++ b/.github/workflows/libc-fullbuild-tests.yml @@ -0,0 +1,89 @@ +# This workflow is for pre-commit testing of the LLVM-libc project. +name: LLVM-libc Pre-commit Fullbuild Tests +permissions: + contents: read +on: + pull_request: + branches: [ "main" ] + paths: + - 'libc/**' + - '.github/workflows/libc-fullbuild-tests.yml' + +jobs: + build: + runs-on: ubuntu-24.04 + strategy: + fail-fast: false + matrix: + include: + - c_compiler: clang + cpp_compiler: clang++ + # TODO: add back gcc build when it is fixed + # - c_compiler: gcc + # cpp_compiler: g++ + steps: + - uses: actions/checkout@v4 + + # Libc's build is relatively small comparing with other components of LLVM. + # A fresh fullbuild takes about 190MiB of uncompressed disk space, which can + # be compressed into ~40MiB. Limiting the cache size to 1G should be enough. + # Prefer sccache as it is more modern. + # Do not use direct GHAC access even though it is supported by sccache. GHAC rejects + # frequent small object writes. + - name: Setup ccache + uses: hendrikmuhs/ccache-action@v1.2 + with: + max-size: 1G + key: libc_fullbuild_${{ matrix.c_compiler }} + variant: sccache + + # Notice: + # - MPFR is required by some of the mathlib tests. + # - Debian has a multilib setup, so we need to symlink the asm directory. + # For more information, see https://wiki.debian.org/Multiarch/LibraryPathOverview + - name: Prepare dependencies (Ubuntu) + run: | + sudo apt-get update + sudo apt-get install -y libmpfr-dev libgmp-dev libmpc-dev ninja-build linux-libc-dev + sudo ln -sf /usr/include/$(uname -p)-linux-gnu/asm /usr/include/asm + + - name: Set reusable strings + id: strings + shell: bash + run: | + echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + echo "build-install-dir=${{ github.workspace }}/install" >> "$GITHUB_OUTPUT" + + # Configure libc fullbuild with scudo. + # Use MinSizeRel to reduce the size of the build. + - name: Configure CMake + run: > + cmake -B ${{ steps.strings.outputs.build-output-dir }} + -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} + -DCMAKE_C_COMPILER=${{ matrix.c_compiler }} + -DCMAKE_BUILD_TYPE=MinSizeRel + -DCMAKE_C_COMPILER_LAUNCHER=sccache + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache + -DCMAKE_INSTALL_PREFIX=${{ steps.strings.outputs.build-install-dir }} + -DLLVM_ENABLE_RUNTIMES="libc;compiler-rt" + -DLLVM_LIBC_FULL_BUILD=ON + -DLLVM_LIBC_INCLUDE_SCUDO=ON + -DCOMPILER_RT_BUILD_SCUDO_STANDALONE_WITH_LLVM_LIBC=ON + -DCOMPILER_RT_BUILD_GWP_ASAN=OFF + -DCOMPILER_RT_SCUDO_STANDALONE_BUILD_SHARED=OFF + -G Ninja + -S ${{ github.workspace }}/runtimes + + - name: Build + run: > + cmake + --build ${{ steps.strings.outputs.build-output-dir }} + --parallel + --target install + + - name: Test + run: > + cmake + --build ${{ steps.strings.outputs.build-output-dir }} + --parallel + --target check-libc diff --git a/.github/workflows/libc-overlay-tests.yml b/.github/workflows/libc-overlay-tests.yml new file mode 100644 index 0000000000000..8b59d76aed4a8 --- /dev/null +++ b/.github/workflows/libc-overlay-tests.yml @@ -0,0 +1,106 @@ +# This workflow is for pre-commit testing of the LLVM-libc project. +name: LLVM-libc Pre-commit Overlay Tests +permissions: + contents: read +on: + pull_request: + branches: [ "main" ] + paths: + - 'libc/**' + - '.github/workflows/libc-overlay-tests.yml' + +jobs: + build: + runs-on: ${{ matrix.os }} + strategy: + # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. + fail-fast: false + matrix: + include: + # TODO: add linux gcc when it is fixed + - os: ubuntu-24.04 + compiler: + c_compiler: clang + cpp_compiler: clang++ + - os: windows-2022 + compiler: + c_compiler: clang-cl + cpp_compiler: clang-cl + - os: macos-14 + compiler: + c_compiler: clang + cpp_compiler: clang++ + + steps: + - uses: actions/checkout@v4 + + # Libc's build is relatively small comparing with other components of LLVM. + # A fresh linux overlay takes about 180MiB of uncompressed disk space, which can + # be compressed into ~40MiB. MacOS and Windows overlay builds are less than 10MiB + # after compression. Limiting the cache size to 1G should be enough. + # Prefer sccache as it is modern and it has a guarantee to work with MSVC. + # Do not use direct GHAC access even though it is supported by sccache. GHAC rejects + # frequent small object writes. + - name: Setup ccache + uses: hendrikmuhs/ccache-action@v1 + with: + max-size: 1G + key: libc_overlay_build_${{ matrix.os }}_${{ matrix.compiler.c_compiler }} + variant: sccache + + # MPFR is required by some of the mathlib tests. + - name: Prepare dependencies (Ubuntu) + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y libmpfr-dev libgmp-dev libmpc-dev ninja-build + + # Chocolatey is shipped with Windows runners. Windows Server 2025 recommends WinGet. + # Consider migrating to WinGet when Windows Server 2025 is available. + - name: Prepare dependencies (Windows) + if: runner.os == 'Windows' + run: | + choco install ninja + + - name: Prepare dependencies (macOS) + if: runner.os == 'macOS' + run: | + brew install ninja + + - name: Set reusable strings + id: strings + shell: bash + run: | + echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + + # Use MinSizeRel to reduce the size of the build. + # Notice that CMP0141=NEW and MSVC_DEBUG_INFORMATION_FORMAT=Embedded are required + # by the sccache tool. + - name: Configure CMake + run: > + cmake -B ${{ steps.strings.outputs.build-output-dir }} + -DCMAKE_CXX_COMPILER=${{ matrix.compiler.cpp_compiler }} + -DCMAKE_C_COMPILER=${{ matrix.compiler.c_compiler }} + -DCMAKE_BUILD_TYPE=MinSizeRel + -DCMAKE_C_COMPILER_LAUNCHER=sccache + -DCMAKE_CXX_COMPILER_LAUNCHER=sccache + -DCMAKE_POLICY_DEFAULT_CMP0141=NEW + -DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=Embedded + -DLLVM_ENABLE_RUNTIMES=libc + -G Ninja + -S ${{ github.workspace }}/runtimes + + - name: Build + run: > + cmake + --build ${{ steps.strings.outputs.build-output-dir }} + --parallel + --config MinSizeRel + --target libc + + - name: Test + run: > + cmake + --build ${{ steps.strings.outputs.build-output-dir }} + --parallel + --target check-libc diff --git a/.github/workflows/libcxx-restart-preempted-jobs.yaml b/.github/workflows/libcxx-restart-preempted-jobs.yaml index cb454974f7287..82d84c01c92af 100644 --- a/.github/workflows/libcxx-restart-preempted-jobs.yaml +++ b/.github/workflows/libcxx-restart-preempted-jobs.yaml @@ -133,19 +133,19 @@ jobs: restart-test: if: github.repository_owner == 'llvm' && (github.event.workflow_run.conclusion == 'failure' || github.event.workflow_run.conclusion == 'cancelled') && github.event.actor.login == 'ldionne' # TESTING ONLY - name: "Restart Job" + name: "Restart Job (test)" permissions: statuses: read checks: write actions: write runs-on: ubuntu-latest steps: - - name: "Restart Job" + - name: "Restart Job (test)" uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea #v7.0.1 with: script: | const FAILURE_REGEX = /Process completed with exit code 1./ - const PREEMPTION_REGEX = /The runner has received a shutdown signal|The operation was canceled/ + const PREEMPTION_REGEX = /(The runner has received a shutdown signal)|(The operation was canceled)/ function log(msg) { core.notice(msg) diff --git a/.github/workflows/premerge.yaml b/.github/workflows/premerge.yaml new file mode 100644 index 0000000000000..d002e65047015 --- /dev/null +++ b/.github/workflows/premerge.yaml @@ -0,0 +1,69 @@ +name: LLVM Premerge Checks + +permissions: + contents: read + +on: + pull_request: + paths: + - .github/workflows/premerge.yaml + push: + branches: + - 'main' + +jobs: + premerge-checks-linux: + if: github.repository_owner == 'llvm' + runs-on: llvm-premerge-linux-runners + concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.push.head }} + cancel-in-progress: true + container: + image: ghcr.io/llvm/ci-ubuntu-22.04:latest + defaults: + run: + shell: bash + steps: + - name: Checkout LLVM + uses: actions/checkout@v4 + with: + fetch-depth: 2 + - name: Setup ccache + uses: hendrikmuhs/ccache-action@v1.2.14 + - name: Build and Test + run: | + git config --global --add safe.directory '*' + + modified_files=$(git diff --name-only HEAD~1...HEAD) + modified_dirs=$(echo "$modified_files" | cut -d'/' -f1 | sort -u) + + echo $modified_files + echo $modified_dirs + + . ./.ci/compute-projects.sh + + all_projects="bolt clang clang-tools-extra compiler-rt cross-project-tests flang libc libclc lld lldb llvm mlir openmp polly pstl" + modified_projects="$(keep-modified-projects ${all_projects})" + + linux_projects_to_test=$(exclude-linux $(compute-projects-to-test 0 ${modified_projects})) + linux_check_targets=$(check-targets ${linux_projects_to_test} | sort | uniq) + linux_projects=$(add-dependencies ${linux_projects_to_test} | sort | uniq) + + linux_runtimes_to_test=$(compute-runtimes-to-test ${linux_projects_to_test}) + linux_runtime_check_targets=$(check-targets ${linux_runtimes_to_test} | sort | uniq) + linux_runtimes=$(echo ${linux_runtimes_to_test} | sort | uniq) + + if [[ "${linux_projects}" == "" ]]; then + echo "No projects to build" + exit 0 + fi + + echo "Building projects: ${linux_projects}" + echo "Running project checks targets: ${linux_check_targets}" + echo "Building runtimes: ${linux_runtimes}" + echo "Running runtimes checks targets: ${linux_runtime_check_targets}" + + export CC=/opt/llvm/bin/clang + export CXX=/opt/llvm/bin/clang++ + + ./.ci/monolithic-linux.sh "$(echo ${linux_projects} | tr ' ' ';')" "$(echo ${linux_check_targets})" "$(echo ${linux_runtimes} | tr ' ' ';')" "$(echo ${linux_runtime_check_targets})" diff --git a/.gitignore b/.gitignore index 0e7c6c7900133..a84268a7f6863 100644 --- a/.gitignore +++ b/.gitignore @@ -59,6 +59,8 @@ autoconf/autom4te.cache # VS2017 and VSCode config files. .vscode .vs +#zed config files +.zed # pythonenv for github Codespaces pythonenv* # clangd index. (".clangd" is a config file now, thus trailing slash) diff --git a/bolt/docs/BinaryAnalysis.md b/bolt/docs/BinaryAnalysis.md new file mode 100644 index 0000000000000..f91b77d046de8 --- /dev/null +++ b/bolt/docs/BinaryAnalysis.md @@ -0,0 +1,20 @@ +# BOLT-based binary analysis + +As part of post-link-time optimizing, BOLT needs to perform a range of analyses +on binaries such as recontructing control flow graphs, and more. + +The `llvm-bolt-binary-analysis` tool enables running requested binary analyses +on binaries, and generating reports. It does this by building on top of the +analyses implemented in the BOLT libraries. + +## Which binary analyses are implemented? + +At the moment, no binary analyses are implemented. + +The goal is to make it easy using a plug-in framework to add your own analyses. + +## How to add your own binary analysis + +_TODO: this section needs to be written. Ideally, we should have a simple +"example" or "template" analysis that can be the starting point for implementing +custom analyses_ diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h index c9b0e103ed514..115e59ca0697e 100644 --- a/bolt/include/bolt/Core/BinaryContext.h +++ b/bolt/include/bolt/Core/BinaryContext.h @@ -28,6 +28,7 @@ #include "llvm/ADT/iterator.h" #include "llvm/BinaryFormat/Dwarf.h" #include "llvm/BinaryFormat/MachO.h" +#include "llvm/ExecutionEngine/Orc/SymbolStringPool.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" @@ -276,11 +277,10 @@ class BinaryContext { void deregisterSectionName(const BinarySection &Section); public: - static Expected> - createBinaryContext(Triple TheTriple, StringRef InputFileName, - SubtargetFeatures *Features, bool IsPIC, - std::unique_ptr DwCtx, - JournalingStreams Logger); + static Expected> createBinaryContext( + Triple TheTriple, std::shared_ptr SSP, + StringRef InputFileName, SubtargetFeatures *Features, bool IsPIC, + std::unique_ptr DwCtx, JournalingStreams Logger); /// Superset of compiler units that will contain overwritten code that needs /// new debug info. In a few cases, functions may end up not being @@ -372,6 +372,7 @@ class BinaryContext { bool hasSymbolsWithFileName() const { return HasSymbolsWithFileName; } void setHasSymbolsWithFileName(bool Value) { HasSymbolsWithFileName = Value; } + std::shared_ptr getSymbolStringPool() { return SSP; } /// Return true if relocations against symbol with a given name /// must be created. bool forceSymbolRelocations(StringRef SymbolName) const; @@ -631,6 +632,8 @@ class BinaryContext { std::unique_ptr TheTriple; + std::shared_ptr SSP; + const Target *TheTarget; std::string TripleName; @@ -807,8 +810,10 @@ class BinaryContext { BinaryContext(std::unique_ptr Ctx, std::unique_ptr DwCtx, - std::unique_ptr TheTriple, const Target *TheTarget, - std::string TripleName, std::unique_ptr MCE, + std::unique_ptr TheTriple, + std::shared_ptr SSP, + const Target *TheTarget, std::string TripleName, + std::unique_ptr MCE, std::unique_ptr MOFI, std::unique_ptr AsmInfo, std::unique_ptr MII, diff --git a/bolt/include/bolt/Core/DIEBuilder.h b/bolt/include/bolt/Core/DIEBuilder.h index d1acba0f26c78..bd22c536c56fc 100644 --- a/bolt/include/bolt/Core/DIEBuilder.h +++ b/bolt/include/bolt/Core/DIEBuilder.h @@ -162,7 +162,7 @@ class DIEBuilder { /// Clone an attribute in reference format. void cloneDieOffsetReferenceAttribute( - DIE &Die, const DWARFUnit &U, const DWARFDie &InputDIE, + DIE &Die, DWARFUnit &U, const DWARFDie &InputDIE, const DWARFAbbreviationDeclaration::AttributeSpec AttrSpec, uint64_t Ref); /// Clone an attribute in block format. diff --git a/bolt/include/bolt/Core/DebugNames.h b/bolt/include/bolt/Core/DebugNames.h index 0e61a0e4f9d9f..cc4e13a481b2d 100644 --- a/bolt/include/bolt/Core/DebugNames.h +++ b/bolt/include/bolt/Core/DebugNames.h @@ -72,8 +72,8 @@ class DWARF5AcceleratorTable { return std::move(FullTableBuffer); } /// Adds a DIE that is referenced across CUs. - void addCrossCUDie(const DIE *Die) { - CrossCUDies.insert({Die->getOffset(), Die}); + void addCrossCUDie(DWARFUnit *Unit, const DIE *Die) { + CrossCUDies.insert({Die->getOffset(), {Unit, Die}}); } /// Returns true if the DIE can generate an entry for a cross cu reference. /// This only checks TAGs of a DIE because when this is invoked DIE might not @@ -145,7 +145,7 @@ class DWARF5AcceleratorTable { llvm::DenseMap CUOffsetsToPatch; // Contains a map of Entry ID to Entry relative offset. llvm::DenseMap EntryRelativeOffsets; - llvm::DenseMap CrossCUDies; + llvm::DenseMap> CrossCUDies; /// Adds Unit to either CUList, LocalTUList or ForeignTUList. /// Input Unit being processed, and DWO ID if Unit is being processed comes /// from a DWO section. @@ -191,6 +191,29 @@ class DWARF5AcceleratorTable { void emitData(); /// Emit augmentation string. void emitAugmentationString() const; + /// Creates a new entry for a given DIE. + std::optional + addEntry(DWARFUnit &DU, const DIE &CurrDie, + const std::optional &DWOID, + const std::optional &Parent, + const std::optional &Name, + const uint32_t NumberParentsInChain); + /// Returns UnitID for a given DWARFUnit. + uint32_t getUnitID(const DWARFUnit &Unit, + const std::optional &DWOID, bool &IsTU); + std::optional getName(DWARFUnit &DU, + const std::optional &DWOID, + const std::string &NameToUse, + DIEValue ValName); + /// Processes a DIE with references to other DIEs for DW_AT_name and + /// DW_AT_linkage_name resolution. + /// If DW_AT_name exists method creates a new entry for this DIE and returns + /// it. + std::optional processReferencedDie( + DWARFUnit &Unit, const DIE &Die, const std::optional &DWOID, + const std::optional &Parent, + const std::string &NameToUse, const uint32_t NumberParentsInChain, + const dwarf::Attribute &Attr); }; } // namespace bolt } // namespace llvm diff --git a/bolt/include/bolt/Passes/ADRRelaxationPass.h b/bolt/include/bolt/Passes/ADRRelaxationPass.h index 1d35a335c0250..b9f92dec7f03b 100644 --- a/bolt/include/bolt/Passes/ADRRelaxationPass.h +++ b/bolt/include/bolt/Passes/ADRRelaxationPass.h @@ -25,7 +25,8 @@ namespace bolt { class ADRRelaxationPass : public BinaryFunctionPass { public: - explicit ADRRelaxationPass() : BinaryFunctionPass(false) {} + explicit ADRRelaxationPass(const cl::opt &PrintPass) + : BinaryFunctionPass(PrintPass) {} const char *getName() const override { return "adr-relaxation"; } diff --git a/bolt/include/bolt/Rewrite/RewriteInstance.h b/bolt/include/bolt/Rewrite/RewriteInstance.h index 73d2857f946cc..42094cb732107 100644 --- a/bolt/include/bolt/Rewrite/RewriteInstance.h +++ b/bolt/include/bolt/Rewrite/RewriteInstance.h @@ -164,6 +164,9 @@ class RewriteInstance { void preregisterSections(); + /// run analyses requested in binary analysis mode. + void runBinaryAnalyses(); + /// Run optimizations that operate at the binary, or post-linker, level. void runOptimizationPasses(); diff --git a/bolt/include/bolt/Utils/CommandLineOpts.h b/bolt/include/bolt/Utils/CommandLineOpts.h index 04bf7db5de952..111eb650c3746 100644 --- a/bolt/include/bolt/Utils/CommandLineOpts.h +++ b/bolt/include/bolt/Utils/CommandLineOpts.h @@ -18,6 +18,7 @@ namespace opts { extern bool HeatmapMode; +extern bool BinaryAnalysisMode; extern llvm::cl::OptionCategory BoltCategory; extern llvm::cl::OptionCategory BoltDiffCategory; @@ -27,6 +28,7 @@ extern llvm::cl::OptionCategory BoltOutputCategory; extern llvm::cl::OptionCategory AggregatorCategory; extern llvm::cl::OptionCategory BoltInstrCategory; extern llvm::cl::OptionCategory HeatmapCategory; +extern llvm::cl::OptionCategory BinaryAnalysisCategory; extern llvm::cl::opt AlignText; extern llvm::cl::opt AlignFunctions; diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp index a808ece12da19..ac96b836ed579 100644 --- a/bolt/lib/Core/BinaryContext.cpp +++ b/bolt/lib/Core/BinaryContext.cpp @@ -123,6 +123,7 @@ void BinaryContext::logBOLTErrorsAndQuitOnFatal(Error E) { BinaryContext::BinaryContext(std::unique_ptr Ctx, std::unique_ptr DwCtx, std::unique_ptr TheTriple, + std::shared_ptr SSP, const Target *TheTarget, std::string TripleName, std::unique_ptr MCE, std::unique_ptr MOFI, @@ -136,12 +137,12 @@ BinaryContext::BinaryContext(std::unique_ptr Ctx, std::unique_ptr DisAsm, JournalingStreams Logger) : Ctx(std::move(Ctx)), DwCtx(std::move(DwCtx)), - TheTriple(std::move(TheTriple)), TheTarget(TheTarget), - TripleName(TripleName), MCE(std::move(MCE)), MOFI(std::move(MOFI)), - AsmInfo(std::move(AsmInfo)), MII(std::move(MII)), STI(std::move(STI)), - InstPrinter(std::move(InstPrinter)), MIA(std::move(MIA)), - MIB(std::move(MIB)), MRI(std::move(MRI)), DisAsm(std::move(DisAsm)), - Logger(Logger), InitialDynoStats(isAArch64()) { + TheTriple(std::move(TheTriple)), SSP(std::move(SSP)), + TheTarget(TheTarget), TripleName(TripleName), MCE(std::move(MCE)), + MOFI(std::move(MOFI)), AsmInfo(std::move(AsmInfo)), MII(std::move(MII)), + STI(std::move(STI)), InstPrinter(std::move(InstPrinter)), + MIA(std::move(MIA)), MIB(std::move(MIB)), MRI(std::move(MRI)), + DisAsm(std::move(DisAsm)), Logger(Logger), InitialDynoStats(isAArch64()) { RegularPageSize = isAArch64() ? RegularPageSizeAArch64 : RegularPageSizeX86; PageAlign = opts::NoHugePages ? RegularPageSize : HugePageSize; } @@ -159,8 +160,9 @@ BinaryContext::~BinaryContext() { /// Create BinaryContext for a given architecture \p ArchName and /// triple \p TripleName. Expected> BinaryContext::createBinaryContext( - Triple TheTriple, StringRef InputFileName, SubtargetFeatures *Features, - bool IsPIC, std::unique_ptr DwCtx, JournalingStreams Logger) { + Triple TheTriple, std::shared_ptr SSP, + StringRef InputFileName, SubtargetFeatures *Features, bool IsPIC, + std::unique_ptr DwCtx, JournalingStreams Logger) { StringRef ArchName = ""; std::string FeaturesStr = ""; switch (TheTriple.getArch()) { @@ -283,8 +285,8 @@ Expected> BinaryContext::createBinaryContext( auto BC = std::make_unique( std::move(Ctx), std::move(DwCtx), std::make_unique(TheTriple), - TheTarget, std::string(TripleName), std::move(MCE), std::move(MOFI), - std::move(AsmInfo), std::move(MII), std::move(STI), + std::move(SSP), TheTarget, std::string(TripleName), std::move(MCE), + std::move(MOFI), std::move(AsmInfo), std::move(MII), std::move(STI), std::move(InstructionPrinter), std::move(MIA), nullptr, std::move(MRI), std::move(DisAsm), Logger); diff --git a/bolt/lib/Core/BinaryEmitter.cpp b/bolt/lib/Core/BinaryEmitter.cpp index f34a94c577921..5019cf31beee3 100644 --- a/bolt/lib/Core/BinaryEmitter.cpp +++ b/bolt/lib/Core/BinaryEmitter.cpp @@ -46,13 +46,17 @@ BreakFunctionNames("break-funcs", cl::Hidden, cl::cat(BoltCategory)); -static cl::list -FunctionPadSpec("pad-funcs", - cl::CommaSeparated, - cl::desc("list of functions to pad with amount of bytes"), - cl::value_desc("func1:pad1,func2:pad2,func3:pad3,..."), - cl::Hidden, - cl::cat(BoltCategory)); +cl::list + FunctionPadSpec("pad-funcs", cl::CommaSeparated, + cl::desc("list of functions to pad with amount of bytes"), + cl::value_desc("func1:pad1,func2:pad2,func3:pad3,..."), + cl::Hidden, cl::cat(BoltCategory)); + +cl::list FunctionPadBeforeSpec( + "pad-funcs-before", cl::CommaSeparated, + cl::desc("list of functions to pad with amount of bytes"), + cl::value_desc("func1:pad1,func2:pad2,func3:pad3,..."), cl::Hidden, + cl::cat(BoltCategory)); static cl::opt MarkFuncs( "mark-funcs", @@ -70,11 +74,12 @@ X86AlignBranchBoundaryHotOnly("x86-align-branch-boundary-hot-only", cl::init(true), cl::cat(BoltOptCategory)); -size_t padFunction(const BinaryFunction &Function) { +size_t padFunction(const cl::list &Spec, + const BinaryFunction &Function) { static std::map FunctionPadding; - if (FunctionPadding.empty() && !FunctionPadSpec.empty()) { - for (std::string &Spec : FunctionPadSpec) { + if (FunctionPadding.empty() && !Spec.empty()) { + for (const std::string &Spec : Spec) { size_t N = Spec.find(':'); if (N == std::string::npos) continue; @@ -319,6 +324,32 @@ bool BinaryEmitter::emitFunction(BinaryFunction &Function, Streamer.emitCodeAlignment(Function.getAlign(), &*BC.STI); } + if (size_t Padding = + opts::padFunction(opts::FunctionPadBeforeSpec, Function)) { + // Handle padFuncsBefore after the above alignment logic but before + // symbol addresses are decided. + if (!BC.HasRelocations) { + BC.errs() << "BOLT-ERROR: -pad-before-funcs is not supported in " + << "non-relocation mode\n"; + exit(1); + } + + // Preserve Function.getMinAlign(). + if (!isAligned(Function.getMinAlign(), Padding)) { + BC.errs() << "BOLT-ERROR: user-requested " << Padding + << " padding bytes before function " << Function + << " is not a multiple of the minimum function alignment (" + << Function.getMinAlign().value() << ").\n"; + exit(1); + } + + LLVM_DEBUG(dbgs() << "BOLT-DEBUG: padding before function " << Function + << " with " << Padding << " bytes\n"); + + // Since the padding is not executed, it can be null bytes. + Streamer.emitFill(Padding, 0); + } + MCContext &Context = Streamer.getContext(); const MCAsmInfo *MAI = Context.getAsmInfo(); @@ -373,7 +404,7 @@ bool BinaryEmitter::emitFunction(BinaryFunction &Function, emitFunctionBody(Function, FF, /*EmitCodeOnly=*/false); // Emit padding if requested. - if (size_t Padding = opts::padFunction(Function)) { + if (size_t Padding = opts::padFunction(opts::FunctionPadSpec, Function)) { LLVM_DEBUG(dbgs() << "BOLT-DEBUG: padding function " << Function << " with " << Padding << " bytes\n"); Streamer.emitFill(Padding, MAI->getTextAlignFillValue()); @@ -730,30 +761,16 @@ void BinaryEmitter::emitJumpTables(const BinaryFunction &BF) { continue; if (opts::PrintJumpTables) JT.print(BC.outs()); - if (opts::JumpTables == JTS_BASIC && BC.HasRelocations) { + if (opts::JumpTables == JTS_BASIC) { JT.updateOriginal(); } else { MCSection *HotSection, *ColdSection; - if (opts::JumpTables == JTS_BASIC) { - // In non-relocation mode we have to emit jump tables in local sections. - // This way we only overwrite them when the corresponding function is - // overwritten. - std::string Name = ".local." + JT.Labels[0]->getName().str(); - std::replace(Name.begin(), Name.end(), '/', '.'); - BinarySection &Section = - BC.registerOrUpdateSection(Name, ELF::SHT_PROGBITS, ELF::SHF_ALLOC); - Section.setAnonymous(true); - JT.setOutputSection(Section); - HotSection = BC.getDataSection(Name); - ColdSection = HotSection; + if (BF.isSimple()) { + HotSection = ReadOnlySection; + ColdSection = ReadOnlyColdSection; } else { - if (BF.isSimple()) { - HotSection = ReadOnlySection; - ColdSection = ReadOnlyColdSection; - } else { - HotSection = BF.hasProfile() ? ReadOnlySection : ReadOnlyColdSection; - ColdSection = HotSection; - } + HotSection = BF.hasProfile() ? ReadOnlySection : ReadOnlyColdSection; + ColdSection = HotSection; } emitJumpTable(JT, HotSection, ColdSection); } diff --git a/bolt/lib/Core/DIEBuilder.cpp b/bolt/lib/Core/DIEBuilder.cpp index 414912ea1c207..80ad583e079d4 100644 --- a/bolt/lib/Core/DIEBuilder.cpp +++ b/bolt/lib/Core/DIEBuilder.cpp @@ -622,7 +622,7 @@ DWARFDie DIEBuilder::resolveDIEReference( } void DIEBuilder::cloneDieOffsetReferenceAttribute( - DIE &Die, const DWARFUnit &U, const DWARFDie &InputDIE, + DIE &Die, DWARFUnit &U, const DWARFDie &InputDIE, const DWARFAbbreviationDeclaration::AttributeSpec AttrSpec, uint64_t Ref) { DIE *NewRefDie = nullptr; DWARFUnit *RefUnit = nullptr; @@ -654,7 +654,7 @@ void DIEBuilder::cloneDieOffsetReferenceAttribute( // Adding referenced DIE to DebugNames to be used when entries are created // that contain cross cu references. if (DebugNamesTable.canGenerateEntryWithCrossCUReference(U, Die, AttrSpec)) - DebugNamesTable.addCrossCUDie(DieInfo.Die); + DebugNamesTable.addCrossCUDie(&U, DieInfo.Die); // no matter forward reference or backward reference, we are supposed // to calculate them in `finish` due to the possible modification of // the DIE. diff --git a/bolt/lib/Core/DebugNames.cpp b/bolt/lib/Core/DebugNames.cpp index 640b29ec36d5c..366c22c38e616 100644 --- a/bolt/lib/Core/DebugNames.cpp +++ b/bolt/lib/Core/DebugNames.cpp @@ -143,7 +143,8 @@ static bool shouldIncludeVariable(const DWARFUnit &Unit, const DIE &Die) { Unit.getFormParams().Format); for (const DWARFExpression::Operation &Expr : LocExpr) if (Expr.getCode() == dwarf::DW_OP_addrx || - Expr.getCode() == dwarf::DW_OP_form_tls_address) + Expr.getCode() == dwarf::DW_OP_form_tls_address || + Expr.getCode() == dwarf::DW_OP_GNU_push_tls_address) return true; return false; } @@ -161,6 +162,7 @@ bool static canProcess(const DWARFUnit &Unit, const DIE &Die, case dwarf::DW_TAG_structure_type: case dwarf::DW_TAG_typedef: case dwarf::DW_TAG_unspecified_type: + case dwarf::DW_TAG_union_type: if (TagsOnly || Die.findAttribute(dwarf::Attribute::DW_AT_name)) return true; return false; @@ -221,134 +223,113 @@ static uint64_t getEntryID(const BOLTDWARF5AccelTableData &Entry) { return reinterpret_cast(&Entry); } -std::optional -DWARF5AcceleratorTable::addAccelTableEntry( - DWARFUnit &Unit, const DIE &Die, const std::optional &DWOID, - const uint32_t NumberParentsInChain, - std::optional &Parent) { - if (Unit.getVersion() < 5 || !NeedToCreate) - return std::nullopt; - std::string NameToUse = ""; - - auto getUnitID = [&](const DWARFUnit &Unit, bool &IsTU, - uint32_t &DieTag) -> uint32_t { - IsTU = Unit.isTypeUnit(); - DieTag = Die.getTag(); - if (IsTU) { - if (DWOID) { - const uint64_t TUHash = cast(&Unit)->getTypeHash(); - auto Iter = TUHashToIndexMap.find(TUHash); - assert(Iter != TUHashToIndexMap.end() && - "Could not find TU hash in map"); - return Iter->second; - } - return LocalTUList.size() - 1; +uint32_t DWARF5AcceleratorTable::getUnitID(const DWARFUnit &Unit, + const std::optional &DWOID, + bool &IsTU) { + IsTU = Unit.isTypeUnit(); + if (IsTU) { + if (DWOID) { + const uint64_t TUHash = cast(&Unit)->getTypeHash(); + auto Iter = TUHashToIndexMap.find(TUHash); + assert(Iter != TUHashToIndexMap.end() && "Could not find TU hash in map"); + return Iter->second; } - return CUList.size() - 1; - }; + return LocalTUList.size() - 1; + } + return CUList.size() - 1; +} - if (!canProcess(Unit, Die, NameToUse, false)) +std::optional DWARF5AcceleratorTable::getName( + DWARFUnit &Unit, const std::optional &DWOID, + const std::string &NameToUse, DIEValue ValName) { + if ((!ValName || ValName.getForm() == dwarf::DW_FORM_string) && + NameToUse.empty()) return std::nullopt; - - // Addes a Unit to either CU, LocalTU or ForeignTU list the first time we - // encounter it. - // Invoking it here so that we don't add Units that don't have any entries. - if (&Unit != CurrentUnit) { - CurrentUnit = &Unit; - addUnit(Unit, DWOID); + std::string Name = ""; + uint64_t NameIndexOffset = 0; + if (NameToUse.empty()) { + NameIndexOffset = ValName.getDIEInteger().getValue(); + if (ValName.getForm() != dwarf::DW_FORM_strp) + NameIndexOffset = getNameOffset(BC, Unit, NameIndexOffset); + // Counts on strings end with '\0'. + Name = std::string(&StrSection.data()[NameIndexOffset]); + } else { + Name = NameToUse; } - - auto getName = [&](DIEValue ValName) -> std::optional { - if ((!ValName || ValName.getForm() == dwarf::DW_FORM_string) && - NameToUse.empty()) - return std::nullopt; - std::string Name = ""; - uint64_t NameIndexOffset = 0; - if (NameToUse.empty()) { - NameIndexOffset = ValName.getDIEInteger().getValue(); - if (ValName.getForm() != dwarf::DW_FORM_strp) - NameIndexOffset = getNameOffset(BC, Unit, NameIndexOffset); - // Counts on strings end with '\0'. - Name = std::string(&StrSection.data()[NameIndexOffset]); - } else { - Name = NameToUse; - } - auto &It = Entries[Name]; - if (It.Values.empty()) { - if (DWOID && NameToUse.empty()) { - // For DWO Unit the offset is in the .debug_str.dwo section. - // Need to find offset for the name in the .debug_str section. - llvm::hash_code Hash = llvm::hash_value(llvm::StringRef(Name)); - auto ItCache = StrCacheToOffsetMap.find(Hash); - if (ItCache == StrCacheToOffsetMap.end()) - NameIndexOffset = MainBinaryStrWriter.addString(Name); - else - NameIndexOffset = ItCache->second; - } - if (!NameToUse.empty()) + auto &It = Entries[Name]; + if (It.Values.empty()) { + if (DWOID && NameToUse.empty()) { + // For DWO Unit the offset is in the .debug_str.dwo section. + // Need to find offset for the name in the .debug_str section. + llvm::hash_code Hash = llvm::hash_value(llvm::StringRef(Name)); + auto ItCache = StrCacheToOffsetMap.find(Hash); + if (ItCache == StrCacheToOffsetMap.end()) NameIndexOffset = MainBinaryStrWriter.addString(Name); - It.StrOffset = NameIndexOffset; - // This the same hash function used in DWARF5AccelTableData. - It.HashValue = caseFoldingDjbHash(Name); + else + NameIndexOffset = ItCache->second; } - return Name; - }; + if (!NameToUse.empty()) + NameIndexOffset = MainBinaryStrWriter.addString(Name); + It.StrOffset = NameIndexOffset; + // This is the same hash function used in DWARF5AccelTableData. + It.HashValue = caseFoldingDjbHash(Name); + } + return Name; +} - auto addEntry = - [&](DIEValue ValName) -> std::optional { - std::optional Name = getName(ValName); - if (!Name) - return std::nullopt; +std::optional DWARF5AcceleratorTable::addEntry( + DWARFUnit &DU, const DIE &CurrDie, const std::optional &DWOID, + const std::optional &Parent, + const std::optional &Name, + const uint32_t NumberParentsInChain) { + if (!Name) + return std::nullopt; - auto &It = Entries[*Name]; - bool IsTU = false; - uint32_t DieTag = 0; - uint32_t UnitID = getUnitID(Unit, IsTU, DieTag); - std::optional SecondIndex = std::nullopt; - if (IsTU && DWOID) { - auto Iter = CUOffsetsToPatch.find(*DWOID); - if (Iter == CUOffsetsToPatch.end()) - BC.errs() << "BOLT-WARNING: [internal-dwarf-warning]: Could not find " - "DWO ID in CU offsets for second Unit Index " - << *Name << ". For DIE at offset: " - << Twine::utohexstr(CurrentUnitOffset + Die.getOffset()) - << ".\n"; - SecondIndex = Iter->second; - } - std::optional ParentOffset = - (Parent ? std::optional(getEntryID(**Parent)) : std::nullopt); - // This will be populated later in writeEntry. - // This way only parent entries get tracked. - // Keeping memory footprint down. - if (ParentOffset) - EntryRelativeOffsets.insert({*ParentOffset, 0}); - bool IsParentRoot = false; - // If there is no parent and no valid Entries in parent chain this is a root - // to be marked with a flag. - if (!Parent && !NumberParentsInChain) - IsParentRoot = true; - It.Values.push_back(new (Allocator) BOLTDWARF5AccelTableData( - Die.getOffset(), ParentOffset, DieTag, UnitID, IsParentRoot, IsTU, - SecondIndex)); - return It.Values.back(); - }; + auto &It = Entries[*Name]; + bool IsTU = false; + uint32_t DieTag = CurrDie.getTag(); + uint32_t UnitID = getUnitID(DU, DWOID, IsTU); + std::optional SecondIndex = std::nullopt; + if (IsTU && DWOID) { + auto Iter = CUOffsetsToPatch.find(*DWOID); + if (Iter == CUOffsetsToPatch.end()) + BC.errs() << "BOLT-WARNING: [internal-dwarf-warning]: Could not find " + "DWO ID in CU offsets for second Unit Index " + << *Name << ". For DIE at offset: " + << Twine::utohexstr(CurrentUnitOffset + CurrDie.getOffset()) + << ".\n"; + SecondIndex = Iter->second; + } + std::optional ParentOffset = + (Parent ? std::optional(getEntryID(**Parent)) : std::nullopt); + // This will be only populated in writeEntry, in order to keep only the parent + // entries, and keep the footprint down. + if (ParentOffset) + EntryRelativeOffsets.insert({*ParentOffset, 0}); + bool IsParentRoot = false; + // If there is no parent and no valid Entries in parent chain this is a root + // to be marked with a flag. + if (!Parent && !NumberParentsInChain) + IsParentRoot = true; + It.Values.push_back(new (Allocator) BOLTDWARF5AccelTableData( + CurrDie.getOffset(), ParentOffset, DieTag, UnitID, IsParentRoot, IsTU, + SecondIndex)); + return It.Values.back(); +} - // Minor optimization not to add entry twice for DW_TAG_namespace if it has no - // DW_AT_name. - if (!(Die.getTag() == dwarf::DW_TAG_namespace && - !Die.findAttribute(dwarf::Attribute::DW_AT_name))) - addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_linkage_name)); - // For the purposes of determining whether a debugging information entry has a - // particular attribute (such as DW_AT_name), if debugging information entry A - // has a DW_AT_specification or DW_AT_abstract_origin attribute pointing to - // another debugging information entry B, any attributes of B are considered - // to be part of A. - auto processReferencedDie = [&](const dwarf::Attribute &Attr) - -> std::optional { - const DIEValue Value = Die.findAttribute(Attr); +std::optional +DWARF5AcceleratorTable::processReferencedDie( + DWARFUnit &Unit, const DIE &Die, const std::optional &DWOID, + const std::optional &Parent, + const std::string &NameToUse, const uint32_t NumberParentsInChain, + const dwarf::Attribute &Attr) { + DIEValue Value = Die.findAttribute(Attr); + if (!Value) + return std::nullopt; + auto getReferenceDie = [&](const DIEValue &Value, const DIE *RefDieUsed) + -> std::optional> { if (!Value) return std::nullopt; - const DIE *EntryDie = nullptr; if (Value.getForm() == dwarf::DW_FORM_ref_addr) { auto Iter = CrossCUDies.find(Value.getDIEInteger().getValue()); if (Iter == CrossCUDies.end()) { @@ -358,24 +339,97 @@ DWARF5AcceleratorTable::addAccelTableEntry( << ".\n"; return std::nullopt; } - EntryDie = Iter->second; - } else { - const DIEEntry &DIEENtry = Value.getDIEEntry(); - EntryDie = &DIEENtry.getEntry(); + return Iter->second; } - - addEntry(EntryDie->findAttribute(dwarf::Attribute::DW_AT_linkage_name)); - return addEntry(EntryDie->findAttribute(dwarf::Attribute::DW_AT_name)); + const DIEEntry &DIEENtry = Value.getDIEEntry(); + return {{&Unit, &DIEENtry.getEntry()}}; }; - if (std::optional Entry = - processReferencedDie(dwarf::Attribute::DW_AT_abstract_origin)) + DIEValue AttrValLinkageName; + DIEValue AttrValName = Die.findAttribute(dwarf::Attribute::DW_AT_name); + DWARFUnit *RefUnit = &Unit; + const DIE *RefDieUsed = &Die; + // It is possible to have DW_TAG_subprogram only with DW_AT_linkage_name that + // DW_AT_abstract_origin/DW_AT_specification point to. + while (!AttrValName) { + std::optional> RefDUDie = + getReferenceDie(Value, RefDieUsed); + if (!RefDUDie) + break; + RefUnit = RefDUDie->first; + const DIE &RefDie = *RefDUDie->second; + RefDieUsed = &RefDie; + if (!AttrValLinkageName) + AttrValLinkageName = + RefDie.findAttribute(dwarf::Attribute::DW_AT_linkage_name); + AttrValName = RefDie.findAttribute(dwarf::Attribute::DW_AT_name); + Value = RefDie.findAttribute(dwarf::Attribute::DW_AT_abstract_origin); + if (!Value) + Value = RefDie.findAttribute(dwarf::Attribute::DW_AT_specification); + } + addEntry(Unit, Die, DWOID, Parent, + getName(*RefUnit, DWOID, NameToUse, AttrValLinkageName), + NumberParentsInChain); + return addEntry(Unit, Die, DWOID, Parent, + getName(*RefUnit, DWOID, NameToUse, AttrValName), + NumberParentsInChain); +} + +std::optional +DWARF5AcceleratorTable::addAccelTableEntry( + DWARFUnit &Unit, const DIE &Die, const std::optional &DWOID, + const uint32_t NumberParentsInChain, + std::optional &Parent) { + if (Unit.getVersion() < 5 || !NeedToCreate) + return std::nullopt; + std::string NameToUse = ""; + + if (!canProcess(Unit, Die, NameToUse, false)) + return std::nullopt; + + // Adds a Unit to either CU, LocalTU or ForeignTU list the first time we + // encounter it. + // Invoking it here so that we don't add Units that don't have any entries. + if (&Unit != CurrentUnit) { + CurrentUnit = &Unit; + addUnit(Unit, DWOID); + } + + // Minor optimization not to add entry twice for DW_TAG_namespace if it has no + // DW_AT_name. + std::optional LinkageEntry = std::nullopt; + DIEValue NameVal = Die.findAttribute(dwarf::Attribute::DW_AT_name); + DIEValue LinkageNameVal = + Die.findAttribute(dwarf::Attribute::DW_AT_linkage_name); + if (!(Die.getTag() == dwarf::DW_TAG_namespace && !NameVal)) + LinkageEntry = addEntry(Unit, Die, DWOID, Parent, + getName(Unit, DWOID, NameToUse, LinkageNameVal), + NumberParentsInChain); + + std::optional NameEntry = + addEntry(Unit, Die, DWOID, Parent, + getName(Unit, DWOID, NameToUse, NameVal), NumberParentsInChain); + if (NameEntry) + return NameEntry; + + // The DIE doesn't have DW_AT_name or DW_AT_linkage_name, so we need to see if + // we can follow other attributes to find them. For the purposes of + // determining whether a debug information entry has a particular + // attribute (such as DW_AT_name), if debug information entry A has a + // DW_AT_specification or DW_AT_abstract_origin attribute pointing to another + // debug information entry B, any attributes of B are considered to be + // part of A. + if (std::optional Entry = processReferencedDie( + Unit, Die, DWOID, Parent, NameToUse, NumberParentsInChain, + dwarf::Attribute::DW_AT_abstract_origin)) return *Entry; - if (std::optional Entry = - processReferencedDie(dwarf::Attribute::DW_AT_specification)) + if (std::optional Entry = processReferencedDie( + Unit, Die, DWOID, Parent, NameToUse, NumberParentsInChain, + dwarf::Attribute::DW_AT_specification)) return *Entry; - return addEntry(Die.findAttribute(dwarf::Attribute::DW_AT_name)); + // This point can be hit by DW_TAG_varialbe that has no DW_AT_name. + return std::nullopt; } /// Algorithm from llvm implementation. diff --git a/bolt/lib/Passes/LongJmp.cpp b/bolt/lib/Passes/LongJmp.cpp index c1b8c03324e0e..e6bd417705e6f 100644 --- a/bolt/lib/Passes/LongJmp.cpp +++ b/bolt/lib/Passes/LongJmp.cpp @@ -138,9 +138,9 @@ BinaryBasicBlock *LongJmpPass::lookupStubFromGroup( const std::pair &RHS) { return LHS.first < RHS.first; }); - if (Cand == Candidates.end()) - return nullptr; - if (Cand != Candidates.begin()) { + if (Cand == Candidates.end()) { + Cand = std::prev(Cand); + } else if (Cand != Candidates.begin()) { const StubTy *LeftCand = std::prev(Cand); if (Cand->first - DotAddress > DotAddress - LeftCand->first) Cand = LeftCand; diff --git a/bolt/lib/Passes/ReorderFunctions.cpp b/bolt/lib/Passes/ReorderFunctions.cpp index 1256d71342b13..f8f6a01526dcc 100644 --- a/bolt/lib/Passes/ReorderFunctions.cpp +++ b/bolt/lib/Passes/ReorderFunctions.cpp @@ -28,7 +28,9 @@ extern cl::OptionCategory BoltOptCategory; extern cl::opt Verbosity; extern cl::opt RandomSeed; -extern size_t padFunction(const bolt::BinaryFunction &Function); +extern size_t padFunction(const cl::list &Spec, + const bolt::BinaryFunction &Function); +extern cl::list FunctionPadSpec, FunctionPadBeforeSpec; extern cl::opt ReorderFunctions; cl::opt ReorderFunctions( @@ -304,8 +306,12 @@ Error ReorderFunctions::runOnFunctions(BinaryContext &BC) { return false; if (B->isIgnored()) return true; - const size_t PadA = opts::padFunction(*A); - const size_t PadB = opts::padFunction(*B); + const size_t PadA = + opts::padFunction(opts::FunctionPadSpec, *A) + + opts::padFunction(opts::FunctionPadBeforeSpec, *A); + const size_t PadB = + opts::padFunction(opts::FunctionPadSpec, *B) + + opts::padFunction(opts::FunctionPadBeforeSpec, *B); if (!PadA || !PadB) { if (PadA) return true; diff --git a/bolt/lib/Rewrite/BinaryPassManager.cpp b/bolt/lib/Rewrite/BinaryPassManager.cpp index b090604183348..6f074d5d1191f 100644 --- a/bolt/lib/Rewrite/BinaryPassManager.cpp +++ b/bolt/lib/Rewrite/BinaryPassManager.cpp @@ -126,6 +126,11 @@ static cl::opt PrintJTFootprintReduction( cl::desc("print function after jt-footprint-reduction pass"), cl::Hidden, cl::cat(BoltOptCategory)); +static cl::opt + PrintAdrRelaxation("print-adr-relaxation", + cl::desc("print functions after ADR Relaxation pass"), + cl::Hidden, cl::cat(BoltOptCategory)); + static cl::opt PrintLongJmp("print-longjmp", cl::desc("print functions after longjmp pass"), cl::Hidden, @@ -493,7 +498,8 @@ Error BinaryFunctionPassManager::runAllPasses(BinaryContext &BC) { Manager.registerPass(std::make_unique()); if (BC.isAArch64()) { - Manager.registerPass(std::make_unique()); + Manager.registerPass( + std::make_unique(PrintAdrRelaxation)); // Tighten branches according to offset differences between branch and // targets. No extra instructions after this pass, otherwise we may have diff --git a/bolt/lib/Rewrite/DWARFRewriter.cpp b/bolt/lib/Rewrite/DWARFRewriter.cpp index 1b5ba8b49d363..308881081321a 100644 --- a/bolt/lib/Rewrite/DWARFRewriter.cpp +++ b/bolt/lib/Rewrite/DWARFRewriter.cpp @@ -1691,7 +1691,8 @@ namespace { std::unique_ptr createDwarfOnlyBC(const object::ObjectFile &File) { return cantFail(BinaryContext::createBinaryContext( - File.makeTriple(), File.getFileName(), nullptr, false, + File.makeTriple(), std::make_shared(), + File.getFileName(), nullptr, false, DWARFContext::create(File, DWARFContext::ProcessDebugRelocations::Ignore, nullptr, "", WithColor::defaultErrorHandler, WithColor::defaultWarningHandler), diff --git a/bolt/lib/Rewrite/JITLinkLinker.cpp b/bolt/lib/Rewrite/JITLinkLinker.cpp index be8f9dd03467e..ba483ae4711df 100644 --- a/bolt/lib/Rewrite/JITLinkLinker.cpp +++ b/bolt/lib/Rewrite/JITLinkLinker.cpp @@ -122,7 +122,7 @@ struct JITLinkLinker::Context : jitlink::JITLinkContext { jitlink::AsyncLookupResult AllResults; for (const auto &Symbol : Symbols) { - std::string SymName = Symbol.first.str(); + std::string SymName = (*Symbol.first).str(); LLVM_DEBUG(dbgs() << "BOLT: looking for " << SymName << "\n"); if (auto Address = Linker.lookupSymbol(SymName)) { @@ -167,7 +167,9 @@ struct JITLinkLinker::Context : jitlink::JITLinkContext { Error notifyResolved(jitlink::LinkGraph &G) override { for (auto *Symbol : G.defined_symbols()) { SymbolInfo Info{Symbol->getAddress().getValue(), Symbol->getSize()}; - Linker.Symtab.insert({Symbol->getName().str(), Info}); + auto Name = + Symbol->hasName() ? (*Symbol->getName()).str() : std::string(); + Linker.Symtab.insert({std::move(Name), Info}); } return Error::success(); @@ -189,7 +191,7 @@ JITLinkLinker::~JITLinkLinker() { cantFail(MM->deallocate(std::move(Allocs))); } void JITLinkLinker::loadObject(MemoryBufferRef Obj, SectionsMapper MapSections) { - auto LG = jitlink::createLinkGraphFromObject(Obj); + auto LG = jitlink::createLinkGraphFromObject(Obj, BC.getSymbolStringPool()); if (auto E = LG.takeError()) { errs() << "BOLT-ERROR: JITLink failed: " << E << '\n'; exit(1); diff --git a/bolt/lib/Rewrite/MachORewriteInstance.cpp b/bolt/lib/Rewrite/MachORewriteInstance.cpp index c328232de61a3..2f05b03290ba3 100644 --- a/bolt/lib/Rewrite/MachORewriteInstance.cpp +++ b/bolt/lib/Rewrite/MachORewriteInstance.cpp @@ -74,7 +74,8 @@ MachORewriteInstance::MachORewriteInstance(object::MachOObjectFile *InputFile, ErrorAsOutParameter EAO(&Err); Relocation::Arch = InputFile->makeTriple().getArch(); auto BCOrErr = BinaryContext::createBinaryContext( - InputFile->makeTriple(), InputFile->getFileName(), nullptr, + InputFile->makeTriple(), std::make_shared(), + InputFile->getFileName(), nullptr, /* IsPIC */ true, DWARFContext::create(*InputFile), {llvm::outs(), llvm::errs()}); if (Error E = BCOrErr.takeError()) { diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp index 3b8baa3821459..04e073152f081 100644 --- a/bolt/lib/Rewrite/RewriteInstance.cpp +++ b/bolt/lib/Rewrite/RewriteInstance.cpp @@ -78,7 +78,6 @@ namespace opts { extern cl::list HotTextMoveSections; extern cl::opt Hugify; extern cl::opt Instrument; -extern cl::opt JumpTables; extern cl::opt KeepNops; extern cl::opt Lite; extern cl::list ReorderData; @@ -356,7 +355,8 @@ RewriteInstance::RewriteInstance(ELFObjectFileBase *File, const int Argc, Relocation::Arch = TheTriple.getArch(); auto BCOrErr = BinaryContext::createBinaryContext( - TheTriple, File->getFileName(), Features.get(), IsPIC, + TheTriple, std::make_shared(), File->getFileName(), + Features.get(), IsPIC, DWARFContext::create(*File, DWARFContext::ProcessDebugRelocations::Ignore, nullptr, opts::DWPPathName, WithColor::defaultErrorHandler, @@ -698,6 +698,11 @@ Error RewriteInstance::run() { if (opts::DiffOnly) return Error::success(); + if (opts::BinaryAnalysisMode) { + runBinaryAnalyses(); + return Error::success(); + } + preregisterSections(); runOptimizationPasses(); @@ -3474,6 +3479,8 @@ void RewriteInstance::runOptimizationPasses() { BC->logBOLTErrorsAndQuitOnFatal(BinaryFunctionPassManager::runAllPasses(*BC)); } +void RewriteInstance::runBinaryAnalyses() {} + void RewriteInstance::preregisterSections() { // Preregister sections before emission to set their order in the output. const unsigned ROFlags = BinarySection::getFlags(/*IsReadOnly*/ true, @@ -3840,20 +3847,6 @@ void RewriteInstance::mapCodeSections(BOLTLinker::SectionMapper MapSection) { assert(Function.getImageSize() <= Function.getMaxSize() && "Unexpected large function"); - // Map jump tables if updating in-place. - if (opts::JumpTables == JTS_BASIC) { - for (auto &JTI : Function.JumpTables) { - JumpTable *JT = JTI.second; - BinarySection &Section = JT->getOutputSection(); - Section.setOutputAddress(JT->getAddress()); - Section.setOutputFileOffset(getFileOffsetForAddress(JT->getAddress())); - LLVM_DEBUG(dbgs() << "BOLT-DEBUG: mapping JT " << Section.getName() - << " to 0x" << Twine::utohexstr(JT->getAddress()) - << '\n'); - MapSection(Section, JT->getAddress()); - } - } - if (!Function.isSplit()) continue; @@ -5636,26 +5629,8 @@ void RewriteInstance::rewriteFile() { if (Function->getImageAddress() == 0 || Function->getImageSize() == 0) continue; - if (Function->getImageSize() > Function->getMaxSize()) { - assert(!BC->isX86() && "Unexpected large function."); - if (opts::Verbosity >= 1) - BC->errs() << "BOLT-WARNING: new function size (0x" - << Twine::utohexstr(Function->getImageSize()) - << ") is larger than maximum allowed size (0x" - << Twine::utohexstr(Function->getMaxSize()) - << ") for function " << *Function << '\n'; - - // Remove jump table sections that this function owns in non-reloc mode - // because we don't want to write them anymore. - if (!BC->HasRelocations && opts::JumpTables == JTS_BASIC) { - for (auto &JTI : Function->JumpTables) { - JumpTable *JT = JTI.second; - BinarySection &Section = JT->getOutputSection(); - BC->deregisterSection(Section); - } - } - continue; - } + assert(Function->getImageSize() <= Function->getMaxSize() && + "Unexpected large function"); const auto HasAddress = [](const FunctionFragment &FF) { return FF.empty() || diff --git a/bolt/lib/Utils/CommandLineOpts.cpp b/bolt/lib/Utils/CommandLineOpts.cpp index de82420a16713..17f090aa61ee9 100644 --- a/bolt/lib/Utils/CommandLineOpts.cpp +++ b/bolt/lib/Utils/CommandLineOpts.cpp @@ -29,6 +29,7 @@ const char *BoltRevision = namespace opts { bool HeatmapMode = false; +bool BinaryAnalysisMode = false; cl::OptionCategory BoltCategory("BOLT generic options"); cl::OptionCategory BoltDiffCategory("BOLTDIFF generic options"); @@ -38,6 +39,7 @@ cl::OptionCategory BoltOutputCategory("Output options"); cl::OptionCategory AggregatorCategory("Data aggregation options"); cl::OptionCategory BoltInstrCategory("BOLT instrumentation options"); cl::OptionCategory HeatmapCategory("Heatmap options"); +cl::OptionCategory BinaryAnalysisCategory("BinaryAnalysis options"); cl::opt AlignText("align-text", cl::desc("alignment of .text section"), cl::Hidden, diff --git a/bolt/test/AArch64/long-jmp-one-stub.s b/bolt/test/AArch64/long-jmp-one-stub.s new file mode 100644 index 0000000000000..cd9e0875a43c4 --- /dev/null +++ b/bolt/test/AArch64/long-jmp-one-stub.s @@ -0,0 +1,32 @@ +## This test verifies that no unnecessary stubs are inserted when each DotAddress increases during a lookup. + +# REQUIRES: system-linux, asserts + +# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o +# RUN: %clang %cflags -O0 %t.o -o %t.exe -Wl,-q +# RUN: link_fdata %s %t.o %t.fdata +# RUN: llvm-bolt %t.exe -o %t.bolt \ +# RUN: --data %t.fdata | FileCheck %s + +# CHECK: BOLT-INFO: Inserted 1 stubs in the hot area and 0 stubs in the cold area. + + .section .text + .global _start + .global far_away_func + + .align 4 + .global _start + .type _start, %function +_start: +# FDATA: 0 [unknown] 0 1 _start 0 0 100 + bl far_away_func + bl far_away_func + ret + .space 0x8000000 + .global far_away_func + .type far_away_func, %function +far_away_func: + add x0, x0, #1 + ret + +.reloc 0, R_AARCH64_NONE diff --git a/bolt/test/AArch64/pad-before-funcs.s b/bolt/test/AArch64/pad-before-funcs.s new file mode 100644 index 0000000000000..3ce0ee5e38389 --- /dev/null +++ b/bolt/test/AArch64/pad-before-funcs.s @@ -0,0 +1,29 @@ +# Test checks that --pad-before-funcs is working as expected. +# It should be able to introduce a configurable offset for the _start symbol. +# It should reject requests which don't obey the code alignment requirement. + +# RUN: llvm-mc -filetype=obj -triple aarch64-unknown-unknown %s -o %t.o +# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -Wl,--section-start=.text=0x4000 +# RUN: llvm-bolt %t.exe -o %t.bolt.0 --pad-funcs-before=_start:0 +# RUN: llvm-bolt %t.exe -o %t.bolt.4 --pad-funcs-before=_start:4 +# RUN: llvm-bolt %t.exe -o %t.bolt.8 --pad-funcs-before=_start:8 + +# RUN: not llvm-bolt %t.exe -o %t.bolt.8 --pad-funcs-before=_start:1 2>&1 | FileCheck --check-prefix=CHECK-BAD-ALIGN %s + +# CHECK-BAD-ALIGN: user-requested 1 padding bytes before function _start(*2) is not a multiple of the minimum function alignment (4). + +# RUN: llvm-objdump --section=.text --disassemble %t.bolt.0 | FileCheck --check-prefix=CHECK-0 %s +# RUN: llvm-objdump --section=.text --disassemble %t.bolt.4 | FileCheck --check-prefix=CHECK-4 %s +# RUN: llvm-objdump --section=.text --disassemble %t.bolt.8 | FileCheck --check-prefix=CHECK-8 %s + +# Trigger relocation mode in bolt. +.reloc 0, R_AARCH64_NONE + +.section .text +.globl _start + +# CHECK-0: 0000000000400000 <_start> +# CHECK-4: 0000000000400004 <_start> +# CHECK-8: 0000000000400008 <_start> +_start: + ret diff --git a/bolt/test/CMakeLists.txt b/bolt/test/CMakeLists.txt index d468ff984840f..6e18b028bddfc 100644 --- a/bolt/test/CMakeLists.txt +++ b/bolt/test/CMakeLists.txt @@ -37,6 +37,7 @@ list(APPEND BOLT_TEST_DEPS lld llvm-config llvm-bolt + llvm-bolt-binary-analysis llvm-bolt-heatmap llvm-bat-dump llvm-dwarfdump diff --git a/bolt/test/X86/dwarf5-debug-names-abstract-origin-linkage-name-only.s b/bolt/test/X86/dwarf5-debug-names-abstract-origin-linkage-name-only.s new file mode 100644 index 0000000000000..8c9817ce91edb --- /dev/null +++ b/bolt/test/X86/dwarf5-debug-names-abstract-origin-linkage-name-only.s @@ -0,0 +1,568 @@ +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %tmain.o +# RUN: %clang %cflags -gdwarf-5 %tmain.o -o %tmain.exe +# RUN: llvm-bolt %tmain.exe -o %tmain.exe.bolt --update-debug-sections +# RUN: llvm-dwarfdump --debug-names %tmain.exe.bolt > %tlog.txt +# RUN: cat %tlog.txt | FileCheck -check-prefix=BOLT %s + +## Tests that bolt can correctly generate debug_names when there is an DW_TAG_inlined_subroutine +## with DW_AT_abstract_origin that points to DW_TAG_subprogram that only has DW_AT_linkage_name. + +# BOLT: Name Index @ 0x0 { +# BOLT-NEXT: Header { +# BOLT-NEXT: Length: 0xA2 +# BOLT-NEXT: Format: DWARF32 +# BOLT-NEXT: Version: 5 +# BOLT-NEXT: CU count: 1 +# BOLT-NEXT: Local TU count: 0 +# BOLT-NEXT: Foreign TU count: 0 +# BOLT-NEXT: Bucket count: 4 +# BOLT-NEXT: Name count: 4 +# BOLT-NEXT: Abbreviations table size: 0x19 +# BOLT-NEXT: Augmentation: 'BOLT' +# BOLT-NEXT: } +# BOLT-NEXT: Compilation Unit offsets [ +# BOLT-NEXT: CU[0]: 0x00000000 +# BOLT-NEXT: ] +# BOLT-NEXT: Abbreviations [ +# BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_inlined_subroutine +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_ref4 +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 0 [ +# BOLT-NEXT: Name 1 { +# BOLT-NEXT: Hash: 0xB888030 +# BOLT-NEXT: String: {{.+}} "int" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: 0x1 +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: 0x0000004a +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 1 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 2 [ +# BOLT-NEXT: Name 2 { +# BOLT-NEXT: Hash: 0x7C9A7F6A +# BOLT-NEXT: String: {{.+}} "main" +# BOLT-NEXT: Entry @ [[REF1:0x[0-9a-f]*]] { +# BOLT-NEXT: Abbrev: [[ABBREV2]] +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: 0x0000004e +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 3 { +# BOLT-NEXT: Hash: 0xB5063CFE +# BOLT-NEXT: String: {{.+}} "_Z3fooi" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV2]] +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: 0x00000024 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: Entry @ 0x96 { +# BOLT-NEXT: Abbrev: [[ABBREV3]] +# BOLT-NEXT: Tag: DW_TAG_inlined_subroutine +# BOLT-NEXT: DW_IDX_die_offset: 0x0000007e +# BOLT-NEXT: DW_IDX_parent: Entry @ [[REF1]] +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 3 [ +# BOLT-NEXT: Name 4 { +# BOLT-NEXT: Hash: 0x7C952063 +# BOLT-NEXT: String: {{.+}} "char" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: 0x0000009f +# BOLT-NEXT: DW_IDX_parent: + +## int foo(int i) { +## return i ++; +## } +## int main(int argc, char* argv[]) { +## int i = 0; +## [[clang::always_inline]] i = foo(argc); +## return i; +## } +## Test was manually modified so that DW_TAG_subprogram only had DW_AT_linkage_name. + + .text + .file "main.cpp" + .globl _Z3fooi + .p2align 4, 0x90 + .type _Z3fooi,@function +_Z3fooi: +.Lfunc_begin0: + .file 0 "/abstractChain" "main.cpp" md5 0x2e29d55fc1320801a8057a4c50643ea1 + .loc 0 1 0 + .loc 0 2 12 prologue_end + .loc 0 2 3 epilogue_begin is_stmt 0 + retq +.Lfunc_end0: + .size _Z3fooi, .Lfunc_end0-_Z3fooi + + .globl main + .p2align 4, 0x90 + .type main,@function +main: +.Lfunc_begin1: + .loc 0 4 0 is_stmt 1 +.Ltmp2: + .loc 0 5 7 prologue_end + .loc 0 6 36 + movl -12(%rbp), %eax +.Ltmp3: + .loc 0 2 12 +.Ltmp4: + .loc 0 6 30 + .loc 0 7 10 + .loc 0 7 3 epilogue_begin is_stmt 0 + retq +.Ltmp5: +.Lfunc_end1: + .size main, .Lfunc_end1-main + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + #.byte 3 # DW_AT_name + #.byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 32 # DW_AT_inline + .byte 33 # DW_FORM_implicit_const + .byte 1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 9 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 10 # Abbreviation Code + .byte 29 # DW_TAG_inlined_subroutine + .byte 1 # DW_CHILDREN_yes + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 88 # DW_AT_call_file + .byte 11 # DW_FORM_data1 + .byte 89 # DW_AT_call_line + .byte 11 # DW_FORM_data1 + .byte 87 # DW_AT_call_column + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 11 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x98 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x15 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long 56 # DW_AT_abstract_origin + .byte 3 # Abbrev [3] 0x2f:0x8 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long 64 # DW_AT_abstract_origin Manually Modified + .byte 0 # End Of Children Mark + .byte 4 # Abbrev [4] 0x38:0x12 DW_TAG_subprogram + .byte 3 # DW_AT_linkage_name + #.byte 4 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long 74 # DW_AT_type + # DW_AT_external + # DW_AT_inline + .byte 5 # Abbrev [5] 0x41:0x8 DW_TAG_formal_parameter + .byte 6 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long 74 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 6 # Abbrev [6] 0x4a:0x4 DW_TAG_base_type + .byte 5 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 7 # Abbrev [7] 0x4e:0x47 DW_TAG_subprogram + .byte 1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 73 # DW_AT_type Manually Modified + # DW_AT_external + .byte 8 # Abbrev [8] 0x5d:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 116 + .byte 8 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 73 # DW_AT_type Manually Modified + .byte 8 # Abbrev [8] 0x68:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 104 + .byte 9 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .long 148 # DW_AT_type Manually Modified + .byte 9 # Abbrev [9] 0x73:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 100 + .byte 6 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 5 # DW_AT_decl_line + .long 73 # DW_AT_type Manually Modified + .byte 10 # Abbrev [10] 0x7e:0x16 DW_TAG_inlined_subroutine + .long 56 # DW_AT_abstract_origin + .byte 2 # DW_AT_low_pc + .long .Ltmp4-.Ltmp3 # DW_AT_high_pc + .byte 0 # DW_AT_call_file + .byte 6 # DW_AT_call_line + .byte 32 # DW_AT_call_column + .byte 3 # Abbrev [3] 0x8b:0x8 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long 64 # DW_AT_abstract_origin Manually Modified + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 11 # Abbrev [11] 0x95:0x5 DW_TAG_pointer_type + .long 153 # DW_AT_type Manually Modified + .byte 11 # Abbrev [11] 0x9a:0x5 DW_TAG_pointer_type + .long 158 # DW_AT_type Manually Modified + .byte 6 # Abbrev [6] 0x9f:0x4 DW_TAG_base_type + .byte 10 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 48 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 20.0.0git" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=24 +.Linfo_string2: + .asciz "/abstractChain" # string offset=33 +.Linfo_string3: + .asciz "foo" # string offset=85 +.Linfo_string4: + .asciz "_Z3fooi" # string offset=89 +.Linfo_string5: + .asciz "int" # string offset=97 +.Linfo_string6: + .asciz "i" # string offset=101 +.Linfo_string7: + .asciz "main" # string offset=103 +.Linfo_string8: + .asciz "argc" # string offset=108 +.Linfo_string9: + .asciz "argv" # string offset=113 +.Linfo_string10: + .asciz "char" # string offset=118 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string4 + .long .Linfo_string3 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string9 + .long .Linfo_string10 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 + .quad .Ltmp3 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 5 # Header: bucket count + .long 5 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 0 # Bucket 2 + .long 3 # Bucket 3 + .long 4 # Bucket 4 + .long 2090499946 # Hash in Bucket 1 + .long -1257882370 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 3 + .long 193491849 # Hash in Bucket 4 + .long 2090147939 # Hash in Bucket 4 + .long .Linfo_string7 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 1: _Z3fooi + .long .Linfo_string5 # String in Bucket 3: int + .long .Linfo_string3 # String in Bucket 4: foo + .long .Linfo_string10 # String in Bucket 4: char + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 4 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 29 # DW_TAG_inlined_subroutine + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames3: +.L2: + .byte 1 # Abbreviation code + .long 78 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L0: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset +.L3: # DW_IDX_parent + .byte 2 # Abbreviation code + .long 126 # DW_IDX_die_offset + .long .L2-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: _Z3fooi +.Lnames2: +.L1: + .byte 3 # Abbreviation code + .long 74 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames0: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 2 # DW_IDX_parent + # Abbreviation code + .long 126 # DW_IDX_die_offset + .long .L2-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: foo +.Lnames4: +.L4: + .byte 3 # Abbreviation code + .long 159 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 20.0.0git" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/dwarf5-debug-names-abstract-origin-specification.s b/bolt/test/X86/dwarf5-debug-names-abstract-origin-specification.s new file mode 100644 index 0000000000000..2075640d6761c --- /dev/null +++ b/bolt/test/X86/dwarf5-debug-names-abstract-origin-specification.s @@ -0,0 +1,829 @@ +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %tmain.o +# RUN: %clang %cflags -gdwarf-5 %tmain.o -o %tmain.exe +# RUN: llvm-bolt %tmain.exe -o %tmain.exe.bolt --update-debug-sections +# RUN: llvm-dwarfdump --debug-names %tmain.exe.bolt > %tlog.txt +# RUN: cat %tlog.txt | FileCheck -check-prefix=BOLT %s + +## This test checks that BOLT correctly generates .debug_names section when there is transative +## DW_AT_name/DW_AT_linkage_name resolution. + +# BOLT: Abbreviations [ +# BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_class_type +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_inlined_subroutine +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_ref4 +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 0 [ +# BOLT-NEXT: Name 1 { +# BOLT-NEXT: Hash: 0xD72418AA +# BOLT-NEXT: String: {{.+}} "_ZL3fooi" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: 0x000000ba +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 1 [ +# BOLT-NEXT: Name 2 { +# BOLT-NEXT: Hash: 0x10614A06 +# BOLT-NEXT: String: {{.+}} "State" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV2]] +# BOLT-NEXT: Tag: DW_TAG_class_type +# BOLT-NEXT: DW_IDX_die_offset: 0x0000002b +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: Entry @ [[REF1:0x[0-9a-f]*]] { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: 0x00000089 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV3]] +# BOLT-NEXT: Tag: DW_TAG_inlined_subroutine +# BOLT-NEXT: DW_IDX_die_offset: 0x000000a3 +# BOLT-NEXT: DW_IDX_parent: Entry @ [[REF1]] +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 2 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 3 [ +# BOLT-NEXT: Name 3 { +# BOLT-NEXT: Hash: 0xB888030 +# BOLT-NEXT: String: {{.+}} "int" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV4]] +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: 0x00000085 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 4 { +# BOLT-NEXT: Hash: 0x7C9A7F6A +# BOLT-NEXT: String: {{.+}} "main" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: 0x00000042 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 4 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 5 [ +# BOLT-NEXT: Name 5 { +# BOLT-NEXT: Hash: 0xB887389 +# BOLT-NEXT: String: {{.+}} "foo" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: 0x000000ba +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 6 { +# BOLT-NEXT: Hash: 0x7C952063 +# BOLT-NEXT: String: {{.+}} "char" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV4]] +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: 0x000000d9 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 7 { +# BOLT-NEXT: Hash: 0xFBBDC812 +# BOLT-NEXT: String: {{.+}} "_ZN5StateC2Ev" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: 0x00000089 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV3]] +# BOLT-NEXT: Tag: DW_TAG_inlined_subroutine +# BOLT-NEXT: DW_IDX_die_offset: 0x000000a3 +# BOLT-NEXT: DW_IDX_parent: Entry @ [[REF1]] + +## static int foo(int i) { +## return i ++; +## } +## class State { +## public: +## State() {[[clang::always_inline]] foo(3);} +## }; +## +## int main(int argc, char* argv[]) { +## State S; +## return 0; +## } + +## Test manually modified to redirect DW_TAG_inlined_subroutine to DW_TAG_subprogram with DW_AT_specification. + + .text + .file "main.cpp" + .file 0 "abstractChainTwo" "main.cpp" md5 0x17ad726b6a1fd49ee59559a1302da539 + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .loc 0 9 0 # main.cpp:9:0 +.Ltmp0: + .loc 0 10 9 prologue_end # main.cpp:10:9 + callq _ZN5StateC2Ev + .loc 0 11 3 # main.cpp:11:3 + .loc 0 11 3 epilogue_begin is_stmt 0 # main.cpp:11:3 + retq +.Ltmp1: +.Lfunc_end0: + .size main, .Lfunc_end0-main + # -- End function + .section .text._ZN5StateC2Ev,"axG",@progbits,_ZN5StateC2Ev,comdat + .weak _ZN5StateC2Ev # -- Begin function _ZN5StateC2Ev + .p2align 4, 0x90 + .type _ZN5StateC2Ev,@function +_ZN5StateC2Ev: # @_ZN5StateC2Ev +.Lfunc_begin1: + .loc 0 6 0 is_stmt 1 # main.cpp:6:0 + .cfi_startproc +# %bb.0: + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movq %rdi, -16(%rbp) + movl $3, -4(%rbp) +.Ltmp2: + .loc 0 2 12 prologue_end # main.cpp:2:12 + movl -4(%rbp), %eax + addl $1, %eax + movl %eax, -4(%rbp) +.Ltmp3: + .loc 0 6 44 epilogue_begin # main.cpp:6:44 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp4: +.Lfunc_end1: + .size _ZN5StateC2Ev, .Lfunc_end1-_ZN5StateC2Ev + .cfi_endproc + # -- End function + .text + .p2align 4, 0x90 # -- Begin function _ZL3fooi + .type _ZL3fooi,@function +_ZL3fooi: # @_ZL3fooi +.Lfunc_begin2: + .loc 0 1 0 # main.cpp:1:0 + .cfi_startproc +# %bb.0: + pushq %rbp + .cfi_def_cfa_offset 16 + .cfi_offset %rbp, -16 + movq %rsp, %rbp + .cfi_def_cfa_register %rbp + movl %edi, -4(%rbp) +.Ltmp5: + .loc 0 2 12 prologue_end # main.cpp:2:12 + movl -4(%rbp), %eax + movl %eax, %ecx + addl $1, %ecx + movl %ecx, -4(%rbp) + .loc 0 2 3 epilogue_begin is_stmt 0 # main.cpp:2:3 + popq %rbp + .cfi_def_cfa %rsp, 8 + retq +.Ltmp6: +.Lfunc_end2: + .size _ZL3fooi, .Lfunc_end2-_ZL3fooi + .cfi_endproc + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 1 # DW_FORM_addr + .byte 85 # DW_AT_ranges + .byte 35 # DW_FORM_rnglistx + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 116 # DW_AT_rnglists_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 2 # DW_TAG_class_type + .byte 1 # DW_CHILDREN_yes + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 60 # DW_AT_declaration + .byte 25 # DW_FORM_flag_present + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 50 # DW_AT_accessibility + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 52 # DW_AT_artificial + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 15 # DW_TAG_pointer_type + .byte 0 # DW_CHILDREN_no + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 8 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 9 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 32 # DW_AT_inline + .byte 33 # DW_FORM_implicit_const + .byte 1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 10 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 11 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 12 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 100 # DW_AT_object_pointer + .byte 19 # DW_FORM_ref4 + .byte 110 # DW_AT_linkage_name + .byte 37 # DW_FORM_strx1 + .byte 71 # DW_AT_specification + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 13 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 52 # DW_AT_artificial + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 14 # Abbreviation Code + .byte 29 # DW_TAG_inlined_subroutine + .byte 1 # DW_CHILDREN_yes + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 88 # DW_AT_call_file + .byte 11 # DW_FORM_data1 + .byte 89 # DW_AT_call_line + .byte 11 # DW_FORM_data1 + .byte 87 # DW_AT_call_column + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 15 # Abbreviation Code + .byte 5 # DW_TAG_formal_parameter + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 16 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 49 # DW_AT_abstract_origin + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0xd7 DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .quad 0 # DW_AT_low_pc + .byte 0 # DW_AT_ranges + .long .Laddr_table_base0 # DW_AT_addr_base + .long .Lrnglists_table_base0 # DW_AT_rnglists_base + .byte 2 # Abbrev [2] 0x2b:0x12 DW_TAG_class_type + .byte 5 # DW_AT_calling_convention + .byte 3 # DW_AT_name + .byte 1 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .byte 3 # Abbrev [3] 0x31:0xb DW_TAG_subprogram + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 6 # DW_AT_decl_line + # DW_AT_declaration + # DW_AT_external + .byte 1 # DW_AT_accessibility + # DW_ACCESS_public + .byte 4 # Abbrev [4] 0x36:0x5 DW_TAG_formal_parameter + .long 61 # DW_AT_type + # DW_AT_artificial + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 5 # Abbrev [5] 0x3d:0x5 DW_TAG_pointer_type + .long 43 # DW_AT_type + .byte 6 # Abbrev [6] 0x42:0x31 DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 8 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 9 # DW_AT_decl_line + .long 133 # DW_AT_type + # DW_AT_external + .byte 7 # Abbrev [7] 0x51:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 120 + .byte 10 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 9 # DW_AT_decl_line + .long 133 # DW_AT_type + .byte 7 # Abbrev [7] 0x5c:0xb DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 112 + .byte 11 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 9 # DW_AT_decl_line + .long 207 # DW_AT_type + .byte 8 # Abbrev [8] 0x67:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 111 + .byte 13 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 10 # DW_AT_decl_line + .long 43 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 9 # Abbrev [9] 0x73:0x12 DW_TAG_subprogram + .byte 4 # DW_AT_linkage_name + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long 133 # DW_AT_type + # DW_AT_inline + .byte 10 # Abbrev [10] 0x7c:0x8 DW_TAG_formal_parameter + .byte 7 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long 133 # DW_AT_type + .byte 0 # End Of Children Mark + .byte 11 # Abbrev [11] 0x85:0x4 DW_TAG_base_type + .byte 6 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 12 # Abbrev [12] 0x89:0x31 DW_TAG_subprogram + .byte 1 # DW_AT_low_pc + .long .Lfunc_end1-.Lfunc_begin1 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long 154 # DW_AT_object_pointer + .byte 9 # DW_AT_linkage_name + .long 49 # DW_AT_specification + .byte 13 # Abbrev [13] 0x9a:0x9 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 112 + .byte 14 # DW_AT_name + .long 221 # DW_AT_type + # DW_AT_artificial + .byte 14 # Abbrev [14] 0xa3:0x16 DW_TAG_inlined_subroutine + .long 137 # DW_AT_abstract_origin Manually Modified + .byte 2 # DW_AT_low_pc + .long .Ltmp3-.Ltmp2 # DW_AT_high_pc + .byte 0 # DW_AT_call_file + .byte 6 # DW_AT_call_line + .byte 37 # DW_AT_call_column + .byte 15 # Abbrev [15] 0xb0:0x8 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long 124 # DW_AT_abstract_origin + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 16 # Abbrev [16] 0xba:0x15 DW_TAG_subprogram + .byte 3 # DW_AT_low_pc + .long .Lfunc_end2-.Lfunc_begin2 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .long 115 # DW_AT_abstract_origin + .byte 15 # Abbrev [15] 0xc6:0x8 DW_TAG_formal_parameter + .byte 2 # DW_AT_location + .byte 145 + .byte 124 + .long 124 # DW_AT_abstract_origin + .byte 0 # End Of Children Mark + .byte 5 # Abbrev [5] 0xcf:0x5 DW_TAG_pointer_type + .long 212 # DW_AT_type + .byte 5 # Abbrev [5] 0xd4:0x5 DW_TAG_pointer_type + .long 217 # DW_AT_type + .byte 11 # Abbrev [11] 0xd9:0x4 DW_TAG_base_type + .byte 12 # DW_AT_name + .byte 6 # DW_AT_encoding + .byte 1 # DW_AT_byte_size + .byte 5 # Abbrev [5] 0xdd:0x5 DW_TAG_pointer_type + .long 43 # DW_AT_type + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_rnglists,"",@progbits + .long .Ldebug_list_header_end0-.Ldebug_list_header_start0 # Length +.Ldebug_list_header_start0: + .short 5 # Version + .byte 8 # Address size + .byte 0 # Segment selector size + .long 1 # Offset entry count +.Lrnglists_table_base0: + .long .Ldebug_ranges0-.Lrnglists_table_base0 +.Ldebug_ranges0: + .byte 1 # DW_RLE_base_addressx + .byte 0 # base address index + .byte 4 # DW_RLE_offset_pair + .uleb128 .Lfunc_begin0-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end0-.Lfunc_begin0 # ending offset + .byte 4 # DW_RLE_offset_pair + .uleb128 .Lfunc_begin2-.Lfunc_begin0 # starting offset + .uleb128 .Lfunc_end2-.Lfunc_begin0 # ending offset + .byte 3 # DW_RLE_startx_length + .byte 1 # start index + .uleb128 .Lfunc_end1-.Lfunc_begin1 # length + .byte 0 # DW_RLE_end_of_list +.Ldebug_list_header_end0: + .section .debug_str_offsets,"",@progbits + .long 64 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 20.0.0git" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=24 +.Linfo_string2: + .asciz "abstractChainTwo" # string offset=33 +.Linfo_string3: + .asciz "State" # string offset=88 +.Linfo_string4: + .asciz "main" # string offset=94 +.Linfo_string5: + .asciz "_ZL3fooi" # string offset=99 +.Linfo_string6: + .asciz "foo" # string offset=108 +.Linfo_string7: + .asciz "int" # string offset=112 +.Linfo_string8: + .asciz "i" # string offset=116 +.Linfo_string9: + .asciz "_ZN5StateC2Ev" # string offset=118 +.Linfo_string10: + .asciz "argc" # string offset=132 +.Linfo_string11: + .asciz "argv" # string offset=137 +.Linfo_string12: + .asciz "char" # string offset=142 +.Linfo_string13: + .asciz "S" # string offset=147 +.Linfo_string14: + .asciz "this" # string offset=149 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string5 + .long .Linfo_string6 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string4 + .long .Linfo_string9 + .long .Linfo_string10 + .long .Linfo_string11 + .long .Linfo_string12 + .long .Linfo_string13 + .long .Linfo_string14 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 + .quad .Lfunc_begin1 + .quad .Ltmp2 + .quad .Lfunc_begin2 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 7 # Header: bucket count + .long 7 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 1 # Bucket 0 + .long 2 # Bucket 1 + .long 0 # Bucket 2 + .long 3 # Bucket 3 + .long 0 # Bucket 4 + .long 5 # Bucket 5 + .long 0 # Bucket 6 + .long -685500246 # Hash in Bucket 0 + .long 274811398 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 3 + .long 2090499946 # Hash in Bucket 3 + .long 193491849 # Hash in Bucket 5 + .long 2090147939 # Hash in Bucket 5 + .long -71448558 # Hash in Bucket 5 + .long .Linfo_string5 # String in Bucket 0: _ZL3fooi + .long .Linfo_string3 # String in Bucket 1: State + .long .Linfo_string7 # String in Bucket 3: int + .long .Linfo_string4 # String in Bucket 3: main + .long .Linfo_string6 # String in Bucket 5: foo + .long .Linfo_string12 # String in Bucket 5: char + .long .Linfo_string9 # String in Bucket 5: _ZN5StateC2Ev + .long .Lnames5-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 5 + .long .Lnames6-.Lnames_entries0 # Offset in Bucket 5 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 5 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 29 # DW_TAG_inlined_subroutine + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 2 # DW_TAG_class_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames5: +.L1: + .byte 1 # Abbreviation code + .long 163 # DW_IDX_die_offset + .long .L2-.Lnames_entries0 # DW_IDX_parent +.L0: + .byte 2 # Abbreviation code + .long 186 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _ZL3fooi +.Lnames0: +.L5: + .byte 3 # Abbreviation code + .long 43 # DW_IDX_die_offset +.L2: # DW_IDX_parent + .byte 2 # Abbreviation code + .long 137 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: State +.Lnames2: +.L4: + .byte 4 # Abbreviation code + .long 133 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames1: +.L6: + .byte 2 # Abbreviation code + .long 66 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames4: + .byte 1 # Abbreviation code + .long 163 # DW_IDX_die_offset + .long .L2-.Lnames_entries0 # DW_IDX_parent + .byte 2 # Abbreviation code + .long 186 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: foo +.Lnames6: +.L3: + .byte 4 # Abbreviation code + .long 217 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: char +.Lnames3: + .byte 2 # Abbreviation code + .long 137 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: _ZN5StateC2Ev + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 20.0.0git" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/dwarf5-debug-names-gnu-push-tls-address.s b/bolt/test/X86/dwarf5-debug-names-gnu-push-tls-address.s new file mode 100644 index 0000000000000..f84d0b6654e7a --- /dev/null +++ b/bolt/test/X86/dwarf5-debug-names-gnu-push-tls-address.s @@ -0,0 +1,291 @@ +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %tmain.o +# RUN: %clang %cflags -gdwarf-5 %tmain.o -o %tmain.exe +# RUN: llvm-bolt %tmain.exe -o %tmain.exe.bolt --update-debug-sections +# RUN: llvm-dwarfdump --debug-names --debug-info %tmain.exe.bolt > %tlog.txt +# RUN: cat %tlog.txt | FileCheck -check-prefix=BOLT %s + +## This test checks that BOLT correctly generates .debug_names section when there is DW_TAG_variable +## with DW_OP_GNU_push_tls_address in DW_AT_location. + +# BOLT: [[DIEOFFSET:0x[0-9a-f]*]]: DW_TAG_variable +# BOLT-NEXT: DW_AT_name ("x") +# BOLT-NEXT: DW_AT_type ({{.+}} "int") +# BOLT-NEXT: DW_AT_external (true) +# BOLT-NEXT: DW_AT_decl_file ("gnu_tls_push/main.cpp") +# BOLT-NEXT: DW_AT_decl_line (1) +# BOLT-NEXT: DW_AT_location (DW_OP_const8u 0x0, DW_OP_GNU_push_tls_address) +# BOLT: Hash: 0x2B61D +# BOLT-NEXT: String: {{.+}} "x" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: {{.+}} +# BOLT-NEXT: Tag: DW_TAG_variable +# BOLT-NEXT: DW_IDX_die_offset: [[DIEOFFSET]] +# BOLT-NEXT: DW_IDX_parent: + +## thread_local int x = 0; +## int main() { +## x = 10; +## return x; +## } + .file "main.cpp" + .file 0 "gnu_tls_push" "main.cpp" md5 0x551db97d5e23dc6a81abdc5ade4d9d71 + .globl main + .type main,@function +main: +.Lfunc_begin0: + .loc 0 2 0 + .loc 0 3 3 prologue_end + .loc 0 3 5 is_stmt 0 + .loc 0 4 10 is_stmt 1 + .loc 0 4 3 epilogue_begin is_stmt 0 + retq +.Lfunc_end0: + .size main, .Lfunc_end0-main + + .hidden _ZTW1x + .weak _ZTW1x + .type _ZTW1x,@function +_ZTW1x: +.Lfunc_begin1: + retq +.Lfunc_end1: + .size _ZTW1x, .Lfunc_end1-_ZTW1x + + .type x,@object + .section .tbss,"awT",@nobits + .globl x +x: + .long 0 + .size x, 4 + + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 0 # DW_CHILDREN_no + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x3e DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x13 DW_TAG_variable + .byte 3 # DW_AT_name + .long 54 # DW_AT_type + # DW_AT_external + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .byte 10 # DW_AT_location + .byte 14 + .quad x@DTPOFF + .byte 224 + .byte 3 # Abbrev [3] 0x36:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 4 # Abbrev [4] 0x3a:0xf DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .long 54 # DW_AT_type + # DW_AT_external + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 28 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 17.0.4" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=137 +.Linfo_string2: + .asciz "gnu_tls_push" # string offset=146 +.Linfo_string3: + .asciz "x" # string offset=184 +.Linfo_string4: + .asciz "int" # string offset=186 +.Linfo_string5: + .asciz "main" # string offset=190 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 3 # Header: bucket count + .long 3 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 1 # Bucket 0 + .long 2 # Bucket 1 + .long 3 # Bucket 2 + .long 177693 # Hash in Bucket 0 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 2 + .long .Linfo_string3 # String in Bucket 0: x + .long .Linfo_string5 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 2: int + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 0 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 2 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 52 # DW_TAG_variable + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames1: +.L2: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: x +.Lnames2: +.L0: + .byte 2 # Abbreviation code + .long 58 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames0: +.L1: + .byte 3 # Abbreviation code + .long 54 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 17.0.4 (https://git.internal.tfbnw.net/repos/git/rw/osmeta/external/llvm-project 8d1fd9f463cb31caf429b83cf7a5baea5f67e54a)" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/dwarf5-debug-names-union.test b/bolt/test/X86/dwarf5-debug-names-union.test new file mode 100644 index 0000000000000..c6da1db684ddc --- /dev/null +++ b/bolt/test/X86/dwarf5-debug-names-union.test @@ -0,0 +1,496 @@ +# RUN: llvm-mc -dwarf-version=5 -filetype=obj -triple x86_64-unknown-linux %s -o %tmain.o +# RUN: %clang %cflags -gdwarf-5 %tmain.o -o %tmain.exe +# RUN: llvm-bolt %tmain.exe -o %tmain.exe.bolt --update-debug-sections +# RUN: llvm-dwarfdump --debug-names %tmain.exe.bolt > %tlog.txt +# RUN: cat %tlog.txt | FileCheck -check-prefix=BOLT %s + +## This test checks that bolt correctly generates entry for DW_TAG_union_type for .debug_name section. + +# BOLT: Abbreviations [ +# BOLT-NEXT: Abbreviation [[ABBREV1:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV2:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_flag_present +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV3:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_union_type +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_ref4 +# BOLT-NEXT: } +# BOLT-NEXT: Abbreviation [[ABBREV4:0x[0-9a-f]*]] { +# BOLT-NEXT: Tag: DW_TAG_structure_type +# BOLT-NEXT: DW_IDX_die_offset: DW_FORM_ref4 +# BOLT-NEXT: DW_IDX_parent: DW_FORM_ref4 +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 0 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 1 [ +# BOLT-NEXT: Name 1 { +# BOLT-NEXT: Hash: 0x7C9A7F6A +# BOLT-NEXT: String: {{.+}} "main" +# BOLT-NEXT: Entry @ [[ENTRY:0x[0-9a-f]*]] { +# BOLT-NEXT: Abbrev: [[ABBREV1]] +# BOLT-NEXT: Tag: DW_TAG_subprogram +# BOLT-NEXT: DW_IDX_die_offset: 0x00000024 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 2 [ +# BOLT-NEXT: EMPTY +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 3 [ +# BOLT-NEXT: Name 2 { +# BOLT-NEXT: Hash: 0xB888030 +# BOLT-NEXT: String: {{.+}} "int" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV2]] +# BOLT-NEXT: Tag: DW_TAG_base_type +# BOLT-NEXT: DW_IDX_die_offset: 0x00000083 +# BOLT-NEXT: DW_IDX_parent: +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 3 { +# BOLT-NEXT: Hash: 0xED0F01B4 +# BOLT-NEXT: String: {{.+}} "MyUnion" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV3]] +# BOLT-NEXT: Tag: DW_TAG_union_type +# BOLT-NEXT: DW_IDX_die_offset: 0x00000049 +# BOLT-NEXT: DW_IDX_parent: Entry @ [[ENTRY]] +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: ] +# BOLT-NEXT: Bucket 4 [ +# BOLT-NEXT: Name 4 { +# BOLT-NEXT: Hash: 0x8AB681F0 +# BOLT-NEXT: String: {{.+}} "MyStruct" +# BOLT-NEXT: Entry @ [[ENTRY2:0x[0-9a-f]*]] { +# BOLT-NEXT: Abbrev: [[ABBREV4]] +# BOLT-NEXT: Tag: DW_TAG_structure_type +# BOLT-NEXT: DW_IDX_die_offset: 0x00000062 +# BOLT-NEXT: DW_IDX_parent: Entry @ [[ENTRY]] +# BOLT-NEXT: } +# BOLT-NEXT: } +# BOLT-NEXT: Name 5 { +# BOLT-NEXT: Hash: 0x8EEF3866 +# BOLT-NEXT: String: {{.+}} "MyUnion2" +# BOLT-NEXT: Entry @ {{.+}} { +# BOLT-NEXT: Abbrev: [[ABBREV3]] +# BOLT-NEXT: Tag: DW_TAG_union_type +# BOLT-NEXT: DW_IDX_die_offset: 0x00000071 +# BOLT-NEXT: DW_IDX_parent: Entry @ [[ENTRY2]] + + +## int main() { +## union MyUnion { +## int a; +## int b; +## }; +## struct MyStruct { +## union MyUnion2 { +## int a; +## }; +## MyUnion2 myUnion2; +## }; +## MyUnion myEnum; +## myEnum.a = 5; +## MyStruct myStruct; +## return myEnum.a + myStruct.myUnion2.a; +## } + + .text + .file "main.cpp" + .globl main # -- Begin function main + .p2align 4, 0x90 + .type main,@function +main: # @main +.Lfunc_begin0: + .file 0 "union" "main.cpp" md5 0xb75b2512f2daa57bbcfe0c29f56d95f4 + .loc 0 1 0 # main.cpp:1:0 + retq +.Lfunc_end0: + .size main, .-main + # -- End function + .section .debug_abbrev,"",@progbits + .byte 1 # Abbreviation Code + .byte 17 # DW_TAG_compile_unit + .byte 1 # DW_CHILDREN_yes + .byte 37 # DW_AT_producer + .byte 37 # DW_FORM_strx1 + .byte 19 # DW_AT_language + .byte 5 # DW_FORM_data2 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 114 # DW_AT_str_offsets_base + .byte 23 # DW_FORM_sec_offset + .byte 16 # DW_AT_stmt_list + .byte 23 # DW_FORM_sec_offset + .byte 27 # DW_AT_comp_dir + .byte 37 # DW_FORM_strx1 + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 115 # DW_AT_addr_base + .byte 23 # DW_FORM_sec_offset + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 2 # Abbreviation Code + .byte 46 # DW_TAG_subprogram + .byte 1 # DW_CHILDREN_yes + .byte 17 # DW_AT_low_pc + .byte 27 # DW_FORM_addrx + .byte 18 # DW_AT_high_pc + .byte 6 # DW_FORM_data4 + .byte 64 # DW_AT_frame_base + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 63 # DW_AT_external + .byte 25 # DW_FORM_flag_present + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 3 # Abbreviation Code + .byte 52 # DW_TAG_variable + .byte 0 # DW_CHILDREN_no + .byte 2 # DW_AT_location + .byte 24 # DW_FORM_exprloc + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 4 # Abbreviation Code + .byte 23 # DW_TAG_union_type + .byte 1 # DW_CHILDREN_yes + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 5 # Abbreviation Code + .byte 13 # DW_TAG_member + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 73 # DW_AT_type + .byte 19 # DW_FORM_ref4 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 56 # DW_AT_data_member_location + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 6 # Abbreviation Code + .byte 19 # DW_TAG_structure_type + .byte 1 # DW_CHILDREN_yes + .byte 54 # DW_AT_calling_convention + .byte 11 # DW_FORM_data1 + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 58 # DW_AT_decl_file + .byte 11 # DW_FORM_data1 + .byte 59 # DW_AT_decl_line + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 7 # Abbreviation Code + .byte 36 # DW_TAG_base_type + .byte 0 # DW_CHILDREN_no + .byte 3 # DW_AT_name + .byte 37 # DW_FORM_strx1 + .byte 62 # DW_AT_encoding + .byte 11 # DW_FORM_data1 + .byte 11 # DW_AT_byte_size + .byte 11 # DW_FORM_data1 + .byte 0 # EOM(1) + .byte 0 # EOM(2) + .byte 0 # EOM(3) + .section .debug_info,"",@progbits +.Lcu_begin0: + .long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit +.Ldebug_info_start0: + .short 5 # DWARF version number + .byte 1 # DWARF Unit Type + .byte 8 # Address Size (in bytes) + .long .debug_abbrev # Offset Into Abbrev. Section + .byte 1 # Abbrev [1] 0xc:0x7b DW_TAG_compile_unit + .byte 0 # DW_AT_producer + .short 33 # DW_AT_language + .byte 1 # DW_AT_name + .long .Lstr_offsets_base0 # DW_AT_str_offsets_base + .long .Lline_table_start0 # DW_AT_stmt_list + .byte 2 # DW_AT_comp_dir + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .long .Laddr_table_base0 # DW_AT_addr_base + .byte 2 # Abbrev [2] 0x23:0x5f DW_TAG_subprogram + .byte 0 # DW_AT_low_pc + .long .Lfunc_end0-.Lfunc_begin0 # DW_AT_high_pc + .byte 1 # DW_AT_frame_base + .byte 86 + .byte 3 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 1 # DW_AT_decl_line + .long 130 # DW_AT_type + # DW_AT_external + .byte 3 # Abbrev [3] 0x32:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 120 + .byte 5 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 12 # DW_AT_decl_line + .long 72 # DW_AT_type + .byte 3 # Abbrev [3] 0x3d:0xb DW_TAG_variable + .byte 2 # DW_AT_location + .byte 145 + .byte 116 + .byte 9 # DW_AT_name + .byte 0 # DW_AT_decl_file + .byte 14 # DW_AT_decl_line + .long 97 # DW_AT_type + .byte 4 # Abbrev [4] 0x48:0x19 DW_TAG_union_type + .byte 5 # DW_AT_calling_convention + .byte 8 # DW_AT_name + .byte 4 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 2 # DW_AT_decl_line + .byte 5 # Abbrev [5] 0x4e:0x9 DW_TAG_member + .byte 6 # DW_AT_name + .long 130 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 3 # DW_AT_decl_line + .byte 0 # DW_AT_data_member_location + .byte 5 # Abbrev [5] 0x57:0x9 DW_TAG_member + .byte 7 # DW_AT_name + .long 130 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 4 # DW_AT_decl_line + .byte 0 # DW_AT_data_member_location + .byte 0 # End Of Children Mark + .byte 6 # Abbrev [6] 0x61:0x20 DW_TAG_structure_type + .byte 5 # DW_AT_calling_convention + .byte 12 # DW_AT_name + .byte 4 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 6 # DW_AT_decl_line + .byte 5 # Abbrev [5] 0x67:0x9 DW_TAG_member + .byte 10 # DW_AT_name + .long 112 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 10 # DW_AT_decl_line + .byte 0 # DW_AT_data_member_location + .byte 4 # Abbrev [4] 0x70:0x10 DW_TAG_union_type + .byte 5 # DW_AT_calling_convention + .byte 11 # DW_AT_name + .byte 4 # DW_AT_byte_size + .byte 0 # DW_AT_decl_file + .byte 7 # DW_AT_decl_line + .byte 5 # Abbrev [5] 0x76:0x9 DW_TAG_member + .byte 6 # DW_AT_name + .long 130 # DW_AT_type + .byte 0 # DW_AT_decl_file + .byte 8 # DW_AT_decl_line + .byte 0 # DW_AT_data_member_location + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 0 # End Of Children Mark + .byte 7 # Abbrev [7] 0x82:0x4 DW_TAG_base_type + .byte 4 # DW_AT_name + .byte 5 # DW_AT_encoding + .byte 4 # DW_AT_byte_size + .byte 0 # End Of Children Mark +.Ldebug_info_end0: + .section .debug_str_offsets,"",@progbits + .long 56 # Length of String Offsets Set + .short 5 + .short 0 +.Lstr_offsets_base0: + .section .debug_str,"MS",@progbits,1 +.Linfo_string0: + .asciz "clang version 20.0.0git" # string offset=0 +.Linfo_string1: + .asciz "main.cpp" # string offset=24 +.Linfo_string2: + .asciz "union" # string offset=33 +.Linfo_string3: + .asciz "main" # string offset=77 +.Linfo_string4: + .asciz "int" # string offset=82 +.Linfo_string5: + .asciz "myEnum" # string offset=86 +.Linfo_string6: + .asciz "MyUnion" # string offset=93 +.Linfo_string7: + .asciz "a" # string offset=101 +.Linfo_string8: + .asciz "b" # string offset=103 +.Linfo_string9: + .asciz "myStruct" # string offset=105 +.Linfo_string10: + .asciz "MyStruct" # string offset=114 +.Linfo_string11: + .asciz "myUnion2" # string offset=123 +.Linfo_string12: + .asciz "MyUnion2" # string offset=132 + .section .debug_str_offsets,"",@progbits + .long .Linfo_string0 + .long .Linfo_string1 + .long .Linfo_string2 + .long .Linfo_string3 + .long .Linfo_string4 + .long .Linfo_string5 + .long .Linfo_string7 + .long .Linfo_string8 + .long .Linfo_string6 + .long .Linfo_string9 + .long .Linfo_string11 + .long .Linfo_string12 + .long .Linfo_string10 + .section .debug_addr,"",@progbits + .long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution +.Ldebug_addr_start0: + .short 5 # DWARF version number + .byte 8 # Address size + .byte 0 # Segment selector size +.Laddr_table_base0: + .quad .Lfunc_begin0 +.Ldebug_addr_end0: + .section .debug_names,"",@progbits + .long .Lnames_end0-.Lnames_start0 # Header: unit length +.Lnames_start0: + .short 5 # Header: version + .short 0 # Header: padding + .long 1 # Header: compilation unit count + .long 0 # Header: local type unit count + .long 0 # Header: foreign type unit count + .long 5 # Header: bucket count + .long 5 # Header: name count + .long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size + .long 8 # Header: augmentation string size + .ascii "LLVM0700" # Header: augmentation string + .long .Lcu_begin0 # Compilation unit 0 + .long 0 # Bucket 0 + .long 1 # Bucket 1 + .long 0 # Bucket 2 + .long 2 # Bucket 3 + .long 4 # Bucket 4 + .long 2090499946 # Hash in Bucket 1 + .long 193495088 # Hash in Bucket 3 + .long -317783628 # Hash in Bucket 3 + .long -1967750672 # Hash in Bucket 4 + .long -1896925082 # Hash in Bucket 4 + .long .Linfo_string3 # String in Bucket 1: main + .long .Linfo_string4 # String in Bucket 3: int + .long .Linfo_string6 # String in Bucket 3: MyUnion + .long .Linfo_string10 # String in Bucket 4: MyStruct + .long .Linfo_string12 # String in Bucket 4: MyUnion2 + .long .Lnames0-.Lnames_entries0 # Offset in Bucket 1 + .long .Lnames1-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames2-.Lnames_entries0 # Offset in Bucket 3 + .long .Lnames3-.Lnames_entries0 # Offset in Bucket 4 + .long .Lnames4-.Lnames_entries0 # Offset in Bucket 4 +.Lnames_abbrev_start0: + .byte 1 # Abbrev code + .byte 46 # DW_TAG_subprogram + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 2 # Abbrev code + .byte 36 # DW_TAG_base_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 25 # DW_FORM_flag_present + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 3 # Abbrev code + .byte 23 # DW_TAG_union_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 4 # Abbrev code + .byte 19 # DW_TAG_structure_type + .byte 3 # DW_IDX_die_offset + .byte 19 # DW_FORM_ref4 + .byte 4 # DW_IDX_parent + .byte 19 # DW_FORM_ref4 + .byte 0 # End of abbrev + .byte 0 # End of abbrev + .byte 0 # End of abbrev list +.Lnames_abbrev_end0: +.Lnames_entries0: +.Lnames0: +.L3: + .byte 1 # Abbreviation code + .long 35 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: main +.Lnames1: +.L1: + .byte 2 # Abbreviation code + .long 130 # DW_IDX_die_offset + .byte 0 # DW_IDX_parent + # End of list: int +.Lnames2: +.L4: + .byte 3 # Abbreviation code + .long 72 # DW_IDX_die_offset + .long .L3-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: MyUnion +.Lnames3: +.L2: + .byte 4 # Abbreviation code + .long 97 # DW_IDX_die_offset + .long .L3-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: MyStruct +.Lnames4: +.L0: + .byte 3 # Abbreviation code + .long 112 # DW_IDX_die_offset + .long .L2-.Lnames_entries0 # DW_IDX_parent + .byte 0 # End of list: MyUnion2 + .p2align 2, 0x0 +.Lnames_end0: + .ident "clang version 20.0.0git" + .section ".note.GNU-stack","",@progbits + .addrsig + .section .debug_line,"",@progbits +.Lline_table_start0: diff --git a/bolt/test/X86/linux-static-keys.s b/bolt/test/X86/linux-static-keys.s index 0bd17a375d882..d34dd640ef879 100644 --- a/bolt/test/X86/linux-static-keys.s +++ b/bolt/test/X86/linux-static-keys.s @@ -35,13 +35,13 @@ _start: .L0: jmp L1 # CHECK: jit -# CHECK-SAME: # ID: 1 {{.*}} # Likely: 0 # InitValue: 1 +# CHECK-SAME: # ID: 1 {{.*}} # Likely: 1 # InitValue: 0 nop L1: .nops 5 - jmp .L0 # CHECK: jit -# CHECK-SAME: # ID: 2 {{.*}} # Likely: 1 # InitValue: 1 +# CHECK-SAME: # ID: 2 {{.*}} # Likely: 0 # InitValue: 0 + jmp .L0 ## Check that a branch profile associated with a NOP is handled properly when ## dynamic branch is created. @@ -67,18 +67,24 @@ foo: .type __start___jump_table, %object __start___jump_table: - .long .L0 - . # Jump address - .long L1 - . # Target address - .quad 1 # Key address + .long .L0 - . # Jump address + .long L1 - . # Target address + .quad fake_static_key + 1 - . # Key address; LSB = 1 : likely - .long L1 - . # Jump address - .long L2 - . # Target address - .quad 0 # Key address + .long L1 - . # Jump address + .long L2 - . # Target address + .quad fake_static_key -. # Key address; LSB = 0 : unlikely .globl __stop___jump_table .type __stop___jump_table, %object __stop___jump_table: +## Staic keys (we just use the label ignoring the format of the keys). + .data + .align 8 +fake_static_key: + .quad 0 + ## Fake Linux Kernel sections. .section __ksymtab,"a",@progbits .section __ksymtab_gpl,"a",@progbits diff --git a/bolt/test/binary-analysis/AArch64/Inputs/dummy.txt b/bolt/test/binary-analysis/AArch64/Inputs/dummy.txt new file mode 100644 index 0000000000000..2995a4d0e7491 --- /dev/null +++ b/bolt/test/binary-analysis/AArch64/Inputs/dummy.txt @@ -0,0 +1 @@ +dummy \ No newline at end of file diff --git a/bolt/test/binary-analysis/AArch64/cmdline-args.test b/bolt/test/binary-analysis/AArch64/cmdline-args.test new file mode 100644 index 0000000000000..e414818644a3b --- /dev/null +++ b/bolt/test/binary-analysis/AArch64/cmdline-args.test @@ -0,0 +1,33 @@ +# This file tests error messages produced on invalid command line arguments. +# It also checks that help messages are generated as expected. + +# Verify that an error message is provided if an input file is missing or incorrect + +RUN: not llvm-bolt-binary-analysis 2>&1 | FileCheck -check-prefix=NOFILEARG %s +NOFILEARG: llvm-bolt-binary-analysis: Not enough positional command line arguments specified! +NOFILEARG-NEXT: Must specify at least 1 positional argument: See: {{.*}}llvm-bolt-binary-analysis --help + +RUN: not llvm-bolt-binary-analysis non-existing-file 2>&1 | FileCheck -check-prefix=NONEXISTINGFILEARG %s +NONEXISTINGFILEARG: llvm-bolt-binary-analysis: 'non-existing-file': No such file or directory. + +RUN: not llvm-bolt-binary-analysis %p/Inputs/dummy.txt 2>&1 | FileCheck -check-prefix=NOELFFILEARG %s +NOELFFILEARG: llvm-bolt-binary-analysis: '{{.*}}/Inputs/dummy.txt': The file was not recognized as a valid object file. + +RUN: %clang %cflags %p/../../Inputs/asm_foo.s %p/../../Inputs/asm_main.c -o %t.exe +RUN: llvm-bolt-binary-analysis %t.exe 2>&1 | FileCheck -check-prefix=VALIDELFFILEARG --allow-empty %s +# Check that there are no BOLT-WARNING or BOLT-ERROR output lines +VALIDELFFILEARG: BOLT-INFO: +VALIDELFFILEARG-NOT: BOLT-WARNING: +VALIDELFFILEARG-NOT: BOLT-ERROR: + +# Check --help output + +RUN: llvm-bolt-binary-analysis --help 2>&1 | FileCheck -check-prefix=HELP %s + +HELP: OVERVIEW: BinaryAnalysis +HELP-EMPTY: +HELP-NEXT: USAGE: llvm-bolt-binary-analysis [options] +HELP-EMPTY: +HELP-NEXT: OPTIONS: +HELP-EMPTY: +HELP-NEXT: Generic Options: diff --git a/bolt/test/binary-analysis/AArch64/lit.local.cfg b/bolt/test/binary-analysis/AArch64/lit.local.cfg new file mode 100644 index 0000000000000..6f247dd52e82f --- /dev/null +++ b/bolt/test/binary-analysis/AArch64/lit.local.cfg @@ -0,0 +1,7 @@ +if "AArch64" not in config.root.targets: + config.unsupported = True + +flags = "--target=aarch64-linux-gnu -nostartfiles -nostdlib -ffreestanding -Wl,--emit-relocs" + +config.substitutions.insert(0, ("%cflags", f"%cflags {flags}")) +config.substitutions.insert(0, ("%cxxflags", f"%cxxflags {flags}")) diff --git a/bolt/test/lit.cfg.py b/bolt/test/lit.cfg.py index da3ae34ba3bdd..0d05229be2bf3 100644 --- a/bolt/test/lit.cfg.py +++ b/bolt/test/lit.cfg.py @@ -110,6 +110,7 @@ ), ToolSubst("llvm-boltdiff", unresolved="fatal"), ToolSubst("llvm-bolt-heatmap", unresolved="fatal"), + ToolSubst("llvm-bolt-binary-analysis", unresolved="fatal"), ToolSubst("llvm-bat-dump", unresolved="fatal"), ToolSubst("perf2bolt", unresolved="fatal"), ToolSubst("yaml2obj", unresolved="fatal"), diff --git a/bolt/test/merge-fdata-bat-no-lbr.test b/bolt/test/merge-fdata-bat-no-lbr.test new file mode 100644 index 0000000000000..fd5cd16263356 --- /dev/null +++ b/bolt/test/merge-fdata-bat-no-lbr.test @@ -0,0 +1,20 @@ +## Check that merge-fdata correctly handles merging two fdata files with both boltedcollection and no_lbr tags. + +# REQUIRES: system-linux + +# RUN: split-file %s %t +# RUN: merge-fdata %t/a.fdata %t/b.fdata -o %t/merged.fdata +# RUN: FileCheck %s --input-file %t/merged.fdata + +# CHECK: boltedcollection +# CHECK: no_lbr +# CHECK: main 2 + +#--- a.fdata +boltedcollection +no_lbr +main 1 +#--- b.fdata +boltedcollection +no_lbr +main 1 diff --git a/bolt/test/merge-fdata-lbr-mode.test b/bolt/test/merge-fdata-lbr-mode.test new file mode 100644 index 0000000000000..2cd3853194288 --- /dev/null +++ b/bolt/test/merge-fdata-lbr-mode.test @@ -0,0 +1,15 @@ +## Check that merge-fdata tool doesn't falsely print no_lbr when not in no-lbr mode + +# REQUIRES: system-linux + +# RUN: split-file %s %t +# RUN: merge-fdata %t/a.fdata %t/b.fdata -o %t/merged.fdata +# RUN: FileCheck %s --input-file %t/merged.fdata + +# CHECK-NOT: no_lbr +# CHECK: 1 main 0 1 main 2 1 3 + +#--- a.fdata +1 main 0 1 main 2 0 1 +#--- b.fdata +1 main 0 1 main 2 1 2 diff --git a/bolt/test/merge-fdata-mixed-bat-no-lbr.test b/bolt/test/merge-fdata-mixed-bat-no-lbr.test new file mode 100644 index 0000000000000..eeb3a0e23b0cc --- /dev/null +++ b/bolt/test/merge-fdata-mixed-bat-no-lbr.test @@ -0,0 +1,16 @@ +## Check that merge-fdata doesn't incorrectly merge two fdata files with boltedcollection and no_lbr tags. + +# REQUIRES: system-linux + +# RUN: split-file %s %t +# RUN: not merge-fdata %t/a.fdata %t/b.fdata 2>&1 | FileCheck %s + +# CHECK: cannot mix profile with and without boltedcollection + +#--- a.fdata +boltedcollection +no_lbr +main 1 +#--- b.fdata +no_lbr +main 1 diff --git a/bolt/test/merge-fdata-mixed-mode.test b/bolt/test/merge-fdata-mixed-mode.test new file mode 100644 index 0000000000000..f897fec5d9db4 --- /dev/null +++ b/bolt/test/merge-fdata-mixed-mode.test @@ -0,0 +1,15 @@ +## Check that merge-fdata tool correctly reports error message +## when trying to merge 'no-lbr' and 'lbr' profiles + +# REQUIRES: system-linux + +# RUN: split-file %s %t +# RUN: not merge-fdata %t/a.fdata %t/b.fdata 2>&1 | FileCheck %s + +# CHECK: cannot mix profile with and without no_lbr + +#--- a.fdata +no_lbr +main 1 +#--- b.fdata +main 1 diff --git a/bolt/test/merge-fdata-no-lbr-mode.test b/bolt/test/merge-fdata-no-lbr-mode.test new file mode 100644 index 0000000000000..9dfad99f79994 --- /dev/null +++ b/bolt/test/merge-fdata-no-lbr-mode.test @@ -0,0 +1,18 @@ +## Check that merge-fdata tool correctly processes fdata files with header +## string produced by no-lbr mode (no_lbr) + +# REQUIRES: system-linux + +# RUN: split-file %s %t +# RUN: merge-fdata %t/a.fdata %t/b.fdata -o %t/merged.fdata +# RUN: FileCheck %s --input-file %t/merged.fdata + +# CHECK: no_lbr +# CHECK: main 2 + +#--- a.fdata +no_lbr +main 1 +#--- b.fdata +no_lbr +main 1 diff --git a/bolt/test/unreadable-profile.test b/bolt/test/unreadable-profile.test index fe1ca93f3221e..4c1cd8af0a62c 100644 --- a/bolt/test/unreadable-profile.test +++ b/bolt/test/unreadable-profile.test @@ -1,4 +1,4 @@ -REQUIRES: system-linux +REQUIRES: system-linux, non-root-user RUN: touch %t.profile && chmod 000 %t.profile RUN: %clang %S/Inputs/hello.c -o %t diff --git a/bolt/tools/CMakeLists.txt b/bolt/tools/CMakeLists.txt index 22ea3b9bd805f..3383902cffc40 100644 --- a/bolt/tools/CMakeLists.txt +++ b/bolt/tools/CMakeLists.txt @@ -7,3 +7,4 @@ add_subdirectory(llvm-bolt-fuzzer) add_subdirectory(bat-dump) add_subdirectory(merge-fdata) add_subdirectory(heatmap) +add_subdirectory(binary-analysis) diff --git a/bolt/tools/binary-analysis/CMakeLists.txt b/bolt/tools/binary-analysis/CMakeLists.txt new file mode 100644 index 0000000000000..841fc5b371185 --- /dev/null +++ b/bolt/tools/binary-analysis/CMakeLists.txt @@ -0,0 +1,19 @@ +set(LLVM_LINK_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} + MC + Object + Support + ) + +add_bolt_tool(llvm-bolt-binary-analysis + binary-analysis.cpp + DISABLE_LLVM_LINK_LLVM_DYLIB + ) + +target_link_libraries(llvm-bolt-binary-analysis + PRIVATE + LLVMBOLTRewrite + LLVMBOLTUtils + ) + +add_dependencies(bolt llvm-bolt-binary-analysis) diff --git a/bolt/tools/binary-analysis/binary-analysis.cpp b/bolt/tools/binary-analysis/binary-analysis.cpp new file mode 100644 index 0000000000000..b03fee3e025ae --- /dev/null +++ b/bolt/tools/binary-analysis/binary-analysis.cpp @@ -0,0 +1,122 @@ +//===- bolt/tools/binary-analysis/binary-analysis.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 +// +//===----------------------------------------------------------------------===// +// +// This is a generic binary analysis tool, where multiple different specific +// binary analyses can be plugged in to. The binary analyses are mostly built +// on top of BOLT components. +// +//===----------------------------------------------------------------------===// + +#include "bolt/Rewrite/RewriteInstance.h" +#include "bolt/Utils/CommandLineOpts.h" +#include "llvm/MC/TargetRegistry.h" +#include "llvm/Object/Binary.h" +#include "llvm/Object/ELFObjectFile.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Errc.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Program.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/VirtualFileSystem.h" + +#define DEBUG_TYPE "bolt" + +using namespace llvm; +using namespace object; +using namespace bolt; + +namespace opts { + +static cl::OptionCategory *BinaryAnalysisCategories[] = { + &BinaryAnalysisCategory}; + +static cl::opt InputFilename(cl::Positional, + cl::desc(""), + cl::Required, + cl::cat(BinaryAnalysisCategory), + cl::sub(cl::SubCommand::getAll())); + +} // namespace opts + +static StringRef ToolName = "llvm-bolt-binary-analysis"; + +static void report_error(StringRef Message, std::error_code EC) { + assert(EC); + errs() << ToolName << ": '" << Message << "': " << EC.message() << ".\n"; + exit(1); +} + +static void report_error(StringRef Message, Error E) { + assert(E); + errs() << ToolName << ": '" << Message << "': " << toString(std::move(E)) + << ".\n"; + exit(1); +} + +void ParseCommandLine(int argc, char **argv) { + cl::HideUnrelatedOptions(ArrayRef(opts::BinaryAnalysisCategories)); + // Register the target printer for --version. + cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); + + cl::ParseCommandLineOptions(argc, argv, "BinaryAnalysis\n"); +} + +static std::string GetExecutablePath(const char *Argv0) { + SmallString<256> ExecutablePath(Argv0); + // Do a PATH lookup if Argv0 isn't a valid path. + if (!llvm::sys::fs::exists(ExecutablePath)) + if (llvm::ErrorOr P = + llvm::sys::findProgramByName(ExecutablePath)) + ExecutablePath = *P; + return std::string(ExecutablePath.str()); +} + +int main(int argc, char **argv) { + // Print a stack trace if we signal out. + sys::PrintStackTraceOnErrorSignal(argv[0]); + PrettyStackTraceProgram X(argc, argv); + + std::string ToolPath = GetExecutablePath(argv[0]); + + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + + // Initialize targets and assembly printers/parsers. + llvm::InitializeAllTargetInfos(); + llvm::InitializeAllTargetMCs(); + llvm::InitializeAllAsmParsers(); + llvm::InitializeAllDisassemblers(); + + llvm::InitializeAllTargets(); + llvm::InitializeAllAsmPrinters(); + + ParseCommandLine(argc, argv); + + opts::BinaryAnalysisMode = true; + + if (!sys::fs::exists(opts::InputFilename)) + report_error(opts::InputFilename, errc::no_such_file_or_directory); + + Expected> BinaryOrErr = + createBinary(opts::InputFilename); + if (Error E = BinaryOrErr.takeError()) + report_error(opts::InputFilename, std::move(E)); + Binary &Binary = *BinaryOrErr.get().getBinary(); + + if (auto *e = dyn_cast(&Binary)) { + auto RIOrErr = RewriteInstance::create(e, argc, argv, ToolPath); + if (Error E = RIOrErr.takeError()) + report_error(opts::InputFilename, std::move(E)); + RewriteInstance &RI = *RIOrErr.get(); + if (Error E = RI.run()) + report_error(opts::InputFilename, std::move(E)); + } + + return EXIT_SUCCESS; +} diff --git a/bolt/tools/merge-fdata/merge-fdata.cpp b/bolt/tools/merge-fdata/merge-fdata.cpp index 89ca46c1c0a8f..74a5f8ca2d477 100644 --- a/bolt/tools/merge-fdata/merge-fdata.cpp +++ b/bolt/tools/merge-fdata/merge-fdata.cpp @@ -22,6 +22,7 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/ThreadPool.h" #include +#include #include #include @@ -265,55 +266,70 @@ bool isYAML(const StringRef Filename) { void mergeLegacyProfiles(const SmallVectorImpl &Filenames) { errs() << "Using legacy profile format.\n"; std::optional BoltedCollection; + std::optional NoLBRCollection; std::mutex BoltedCollectionMutex; - typedef StringMap ProfileTy; + struct CounterTy { + uint64_t Exec{0}; + uint64_t Mispred{0}; + CounterTy &operator+=(const CounterTy &O) { + Exec += O.Exec; + Mispred += O.Mispred; + return *this; + } + CounterTy operator+(const CounterTy &O) { return *this += O; } + }; + typedef StringMap ProfileTy; auto ParseProfile = [&](const std::string &Filename, auto &Profiles) { const llvm::thread::id tid = llvm::this_thread::get_id(); if (isYAML(Filename)) report_error(Filename, "cannot mix YAML and legacy formats"); - ErrorOr> MB = - MemoryBuffer::getFileOrSTDIN(Filename); - if (std::error_code EC = MB.getError()) - report_error(Filename, EC); - StringRef Buf = MB.get()->getBuffer(); + std::ifstream FdataFile(Filename, std::ios::in); + std::string FdataLine; + std::getline(FdataFile, FdataLine); + + auto checkMode = [&](const std::string &Key, std::optional &Flag) { + const bool KeyIsSet = FdataLine.rfind(Key, 0) == 0; + + if (!Flag.has_value()) + Flag = KeyIsSet; + else if (*Flag != KeyIsSet) + report_error(Filename, "cannot mix profile with and without " + Key); + if (KeyIsSet) + // Advance line + std::getline(FdataFile, FdataLine); + }; + ProfileTy *Profile; { std::lock_guard Lock(BoltedCollectionMutex); // Check if the string "boltedcollection" is in the first line - if (Buf.starts_with("boltedcollection\n")) { - if (!BoltedCollection.value_or(true)) - report_error( - Filename, - "cannot mix profile collected in BOLT and non-BOLT deployments"); - BoltedCollection = true; - Buf = Buf.drop_front(17); - } else { - if (BoltedCollection.value_or(false)) - report_error( - Filename, - "cannot mix profile collected in BOLT and non-BOLT deployments"); - BoltedCollection = false; - } - + checkMode("boltedcollection", BoltedCollection); + // Check if the string "no_lbr" is in the first line + // (or second line if BoltedCollection is true) + checkMode("no_lbr", NoLBRCollection); Profile = &Profiles[tid]; } - SmallVector Lines; - SplitString(Buf, Lines, "\n"); - for (StringRef Line : Lines) { - size_t Pos = Line.rfind(" "); - if (Pos == StringRef::npos) - report_error(Filename, "Malformed / corrupted profile"); - StringRef Signature = Line.substr(0, Pos); - uint64_t Count; - if (Line.substr(Pos + 1, Line.size() - Pos).getAsInteger(10, Count)) - report_error(Filename, "Malformed / corrupted profile counter"); + do { + StringRef Line(FdataLine); + CounterTy Count; + auto [Signature, ExecCount] = Line.rsplit(' '); + if (ExecCount.getAsInteger(10, Count.Exec)) + report_error(Filename, "Malformed / corrupted execution count"); + // Only LBR profile has misprediction field + if (!NoLBRCollection.value_or(false)) { + auto [SignatureLBR, MispredCount] = Signature.rsplit(' '); + Signature = SignatureLBR; + if (MispredCount.getAsInteger(10, Count.Mispred)) + report_error(Filename, "Malformed / corrupted misprediction count"); + } + Count += Profile->lookup(Signature); Profile->insert_or_assign(Signature, Count); - } + } while (std::getline(FdataFile, FdataLine)); }; // The final reduction has non-trivial cost, make sure each thread has at @@ -330,14 +346,20 @@ void mergeLegacyProfiles(const SmallVectorImpl &Filenames) { ProfileTy MergedProfile; for (const auto &[Thread, Profile] : ParsedProfiles) for (const auto &[Key, Value] : Profile) { - uint64_t Count = MergedProfile.lookup(Key) + Value; + CounterTy Count = MergedProfile.lookup(Key) + Value; MergedProfile.insert_or_assign(Key, Count); } if (BoltedCollection.value_or(false)) output() << "boltedcollection\n"; - for (const auto &[Key, Value] : MergedProfile) - output() << Key << " " << Value << "\n"; + if (NoLBRCollection.value_or(false)) + output() << "no_lbr\n"; + for (const auto &[Key, Value] : MergedProfile) { + output() << Key << " "; + if (!NoLBRCollection.value_or(false)) + output() << Value.Mispred << " "; + output() << Value.Exec << "\n"; + } errs() << "Profile from " << Filenames.size() << " files merged.\n"; } diff --git a/bolt/unittests/Core/BinaryContext.cpp b/bolt/unittests/Core/BinaryContext.cpp index 05b898d34af56..9819a8c2b777b 100644 --- a/bolt/unittests/Core/BinaryContext.cpp +++ b/bolt/unittests/Core/BinaryContext.cpp @@ -48,7 +48,8 @@ struct BinaryContextTester : public testing::TestWithParam { void initializeBOLT() { Relocation::Arch = ObjFile->makeTriple().getArch(); BC = cantFail(BinaryContext::createBinaryContext( - ObjFile->makeTriple(), ObjFile->getFileName(), nullptr, true, + ObjFile->makeTriple(), std::make_shared(), + ObjFile->getFileName(), nullptr, true, DWARFContext::create(*ObjFile.get()), {llvm::outs(), llvm::errs()})); ASSERT_FALSE(!BC); } @@ -216,4 +217,4 @@ TEST_P(BinaryContextTester, BaseAddressSegmentsSmallerThanAlignment) { BC->getBaseAddressForMapping(0xaaaaaaab1000, 0x1000); ASSERT_TRUE(BaseAddress.has_value()); ASSERT_EQ(*BaseAddress, 0xaaaaaaaa0000ULL); -} \ No newline at end of file +} diff --git a/bolt/unittests/Core/MCPlusBuilder.cpp b/bolt/unittests/Core/MCPlusBuilder.cpp index cd6f24c4570a7..5488cae366284 100644 --- a/bolt/unittests/Core/MCPlusBuilder.cpp +++ b/bolt/unittests/Core/MCPlusBuilder.cpp @@ -58,7 +58,8 @@ struct MCPlusBuilderTester : public testing::TestWithParam { void initializeBolt() { Relocation::Arch = ObjFile->makeTriple().getArch(); BC = cantFail(BinaryContext::createBinaryContext( - ObjFile->makeTriple(), ObjFile->getFileName(), nullptr, true, + ObjFile->makeTriple(), std::make_shared(), + ObjFile->getFileName(), nullptr, true, DWARFContext::create(*ObjFile.get()), {llvm::outs(), llvm::errs()})); ASSERT_FALSE(!BC); BC->initializeTarget(std::unique_ptr( diff --git a/bolt/unittests/Core/MemoryMaps.cpp b/bolt/unittests/Core/MemoryMaps.cpp index 230fd314142e8..06073d0a82e14 100644 --- a/bolt/unittests/Core/MemoryMaps.cpp +++ b/bolt/unittests/Core/MemoryMaps.cpp @@ -59,7 +59,8 @@ struct MemoryMapsTester : public testing::TestWithParam { void initializeBOLT() { Relocation::Arch = ObjFile->makeTriple().getArch(); BC = cantFail(BinaryContext::createBinaryContext( - ObjFile->makeTriple(), ObjFile->getFileName(), nullptr, true, + ObjFile->makeTriple(), std::make_shared(), + ObjFile->getFileName(), nullptr, true, DWARFContext::create(*ObjFile.get()), {llvm::outs(), llvm::errs()})); ASSERT_FALSE(!BC); } diff --git a/clang-tools-extra/clang-doc/MDGenerator.cpp b/clang-tools-extra/clang-doc/MDGenerator.cpp index 795eb4b904e3e..28b645cf021dd 100644 --- a/clang-tools-extra/clang-doc/MDGenerator.cpp +++ b/clang-tools-extra/clang-doc/MDGenerator.cpp @@ -157,17 +157,17 @@ static void genMarkdown(const ClangDocContext &CDCtx, const FunctionInfo &I, for (const auto &N : I.Params) { if (!First) Stream << ", "; - Stream << N.Type.Name + " " + N.Name; + Stream << N.Type.QualName + " " + N.Name; First = false; } writeHeader(I.Name, 3, OS); std::string Access = getAccessSpelling(I.Access).str(); if (Access != "") - writeLine(genItalic(Access + " " + I.ReturnType.Type.Name + " " + I.Name + - "(" + Stream.str() + ")"), + writeLine(genItalic(Access + " " + I.ReturnType.Type.QualName + " " + + I.Name + "(" + Stream.str() + ")"), OS); else - writeLine(genItalic(I.ReturnType.Type.Name + " " + I.Name + "(" + + writeLine(genItalic(I.ReturnType.Type.QualName + " " + I.Name + "(" + Stream.str() + ")"), OS); if (I.DefLoc) diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h index 97e16a12febd0..ff42f96a0477b 100644 --- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h +++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.h @@ -81,6 +81,9 @@ class ClangTidyContext { ~ClangTidyContext(); + ClangTidyContext(const ClangTidyContext &) = delete; + ClangTidyContext &operator=(const ClangTidyContext &) = delete; + /// Report any errors detected using this method. /// /// This is still under heavy development and will likely change towards using diff --git a/clang-tools-extra/clang-tidy/NoLintDirectiveHandler.h b/clang-tools-extra/clang-tidy/NoLintDirectiveHandler.h index e862195abaabb..f66285672d04a 100644 --- a/clang-tools-extra/clang-tidy/NoLintDirectiveHandler.h +++ b/clang-tools-extra/clang-tidy/NoLintDirectiveHandler.h @@ -31,6 +31,8 @@ class NoLintDirectiveHandler { public: NoLintDirectiveHandler(); ~NoLintDirectiveHandler(); + NoLintDirectiveHandler(const NoLintDirectiveHandler &) = delete; + NoLintDirectiveHandler &operator=(const NoLintDirectiveHandler &) = delete; bool shouldSuppress(DiagnosticsEngine::Level DiagLevel, const Diagnostic &Diag, llvm::StringRef DiagName, diff --git a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt index b0a2318acc059..13adad7c3dadb 100644 --- a/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/bugprone/CMakeLists.txt @@ -16,6 +16,7 @@ add_clang_library(clangTidyBugproneModule STATIC ChainedComparisonCheck.cpp ComparePointerToMemberVirtualFunctionCheck.cpp CopyConstructorInitCheck.cpp + CrtpConstructorAccessibilityCheck.cpp DanglingHandleCheck.cpp DynamicStaticInitializersCheck.cpp EasilySwappableParametersCheck.cpp @@ -26,11 +27,8 @@ add_clang_library(clangTidyBugproneModule STATIC ForwardingReferenceOverloadCheck.cpp ImplicitWideningOfMultiplicationResultCheck.cpp InaccurateEraseCheck.cpp - IncorrectEnableIfCheck.cpp - ReturnConstRefFromParameterCheck.cpp - SuspiciousStringviewDataUsageCheck.cpp - SwitchMissingDefaultCaseCheck.cpp IncDecInConditionsCheck.cpp + IncorrectEnableIfCheck.cpp IncorrectRoundingsCheck.cpp InfiniteLoopCheck.cpp IntegerDivisionCheck.cpp @@ -45,8 +43,8 @@ add_clang_library(clangTidyBugproneModule STATIC MultipleNewInOneExpressionCheck.cpp MultipleStatementMacroCheck.cpp NoEscapeCheck.cpp - NondeterministicPointerIterationOrderCheck.cpp NonZeroEnumToBoolConversionCheck.cpp + NondeterministicPointerIterationOrderCheck.cpp NotNullTerminatedResultCheck.cpp OptionalValueConversionCheck.cpp ParentVirtualCallCheck.cpp @@ -54,6 +52,7 @@ add_clang_library(clangTidyBugproneModule STATIC PosixReturnCheck.cpp RedundantBranchConditionCheck.cpp ReservedIdentifierCheck.cpp + ReturnConstRefFromParameterCheck.cpp SharedPtrArrayMismatchCheck.cpp SignalHandlerCheck.cpp SignedCharMisuseCheck.cpp @@ -74,7 +73,9 @@ add_clang_library(clangTidyBugproneModule STATIC SuspiciousReallocUsageCheck.cpp SuspiciousSemicolonCheck.cpp SuspiciousStringCompareCheck.cpp + SuspiciousStringviewDataUsageCheck.cpp SwappedArgumentsCheck.cpp + SwitchMissingDefaultCaseCheck.cpp TaggedUnionMemberCountCheck.cpp TerminatingContinueCheck.cpp ThrowKeywordMissingCheck.cpp @@ -85,7 +86,6 @@ add_clang_library(clangTidyBugproneModule STATIC UnhandledExceptionAtNewCheck.cpp UnhandledSelfAssignmentCheck.cpp UniquePtrArrayMismatchCheck.cpp - CrtpConstructorAccessibilityCheck.cpp UnsafeFunctionsCheck.cpp UnusedLocalNonTrivialVariableCheck.cpp UnusedRaiiCheck.cpp diff --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp index 2b2d80ea9346b..b7f0c08b2a7d4 100644 --- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp @@ -13,13 +13,15 @@ #include "clang/Analysis/Analyses/ExprMutationAnalyzer.h" #include "clang/Analysis/CallGraph.h" #include "llvm/ADT/SCCIterator.h" -#include "llvm/ADT/SmallVector.h" using namespace clang::ast_matchers; +using clang::ast_matchers::internal::Matcher; using clang::tidy::utils::hasPtrOrReferenceInFunc; namespace clang { -namespace ast_matchers { +namespace tidy::bugprone { + +namespace { /// matches a Decl if it has a "no return" attribute of any kind AST_MATCHER(Decl, declHasNoReturnAttr) { return Node.hasAttr() || Node.hasAttr() || @@ -30,23 +32,21 @@ AST_MATCHER(Decl, declHasNoReturnAttr) { AST_MATCHER(FunctionType, typeHasNoReturnAttr) { return Node.getNoReturnAttr(); } -} // namespace ast_matchers -namespace tidy::bugprone { +} // namespace -static internal::Matcher -loopEndingStmt(internal::Matcher Internal) { - internal::Matcher isNoReturnFunType = +static Matcher loopEndingStmt(Matcher Internal) { + Matcher IsNoReturnFunType = ignoringParens(functionType(typeHasNoReturnAttr())); - internal::Matcher isNoReturnDecl = - anyOf(declHasNoReturnAttr(), functionDecl(hasType(isNoReturnFunType)), - varDecl(hasType(blockPointerType(pointee(isNoReturnFunType))))); + Matcher IsNoReturnDecl = + anyOf(declHasNoReturnAttr(), functionDecl(hasType(IsNoReturnFunType)), + varDecl(hasType(blockPointerType(pointee(IsNoReturnFunType))))); return stmt(anyOf( mapAnyOf(breakStmt, returnStmt, gotoStmt, cxxThrowExpr).with(Internal), callExpr(Internal, callee(mapAnyOf(functionDecl, /* block callee */ varDecl) - .with(isNoReturnDecl))), - objcMessageExpr(Internal, callee(isNoReturnDecl)))); + .with(IsNoReturnDecl))), + objcMessageExpr(Internal, callee(IsNoReturnDecl)))); } /// Return whether `Var` was changed in `LoopStmt`. diff --git a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp index 600eab3755276..55ca4809f058a 100644 --- a/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/OptionalValueConversionCheck.cpp @@ -12,20 +12,43 @@ #include "../utils/OptionsUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" +#include using namespace clang::ast_matchers; +using clang::ast_matchers::internal::Matcher; namespace clang::tidy::bugprone { namespace { -AST_MATCHER_P(QualType, hasCleanType, ast_matchers::internal::Matcher, - InnerMatcher) { +AST_MATCHER_P(QualType, hasCleanType, Matcher, InnerMatcher) { return InnerMatcher.matches( Node.getNonReferenceType().getUnqualifiedType().getCanonicalType(), Finder, Builder); } +constexpr std::array NameList{ + "::std::make_unique", + "::std::make_shared", +}; + +Matcher constructFrom(Matcher TypeMatcher, + Matcher ArgumentMatcher) { + return expr( + anyOf( + // construct optional + cxxConstructExpr(argumentCountIs(1U), hasType(TypeMatcher), + hasArgument(0U, ArgumentMatcher)), + // known template methods in std + callExpr(argumentCountIs(1), + callee(functionDecl( + matchers::matchesAnyListedName(NameList), + hasTemplateArgument(0, refersToType(TypeMatcher)))), + hasArgument(0, ArgumentMatcher))), + unless(anyOf(hasAncestor(typeLoc()), + hasAncestor(expr(matchers::hasUnevaluatedContext()))))); +} + } // namespace OptionalValueConversionCheck::OptionalValueConversionCheck( @@ -43,18 +66,20 @@ OptionalValueConversionCheck::getCheckTraversalKind() const { } void OptionalValueConversionCheck::registerMatchers(MatchFinder *Finder) { - auto ConstructTypeMatcher = - qualType(hasCleanType(qualType().bind("optional-type"))); + auto BindOptionalType = qualType( + hasCleanType(qualType(hasDeclaration(namedDecl( + matchers::matchesAnyListedName(OptionalTypes)))) + .bind("optional-type"))); - auto CallTypeMatcher = + auto EqualsBoundOptionalType = qualType(hasCleanType(equalsBoundNode("optional-type"))); auto OptionalDereferenceMatcher = callExpr( anyOf( cxxOperatorCallExpr(hasOverloadedOperatorName("*"), - hasUnaryOperand(hasType(CallTypeMatcher))) + hasUnaryOperand(hasType(EqualsBoundOptionalType))) .bind("op-call"), - cxxMemberCallExpr(thisPointerType(CallTypeMatcher), + cxxMemberCallExpr(thisPointerType(EqualsBoundOptionalType), callee(cxxMethodDecl(anyOf( hasOverloadedOperatorName("*"), matchers::matchesAnyListedName(ValueMethods))))) @@ -65,15 +90,9 @@ void OptionalValueConversionCheck::registerMatchers(MatchFinder *Finder) { callExpr(argumentCountIs(1), callee(functionDecl(hasName("::std::move"))), hasArgument(0, ignoringImpCasts(OptionalDereferenceMatcher))); Finder->addMatcher( - cxxConstructExpr( - argumentCountIs(1U), - hasDeclaration(cxxConstructorDecl( - ofClass(matchers::matchesAnyListedName(OptionalTypes)))), - hasType(ConstructTypeMatcher), - hasArgument(0U, ignoringImpCasts(anyOf(OptionalDereferenceMatcher, - StdMoveCallMatcher))), - unless(anyOf(hasAncestor(typeLoc()), - hasAncestor(expr(matchers::hasUnevaluatedContext()))))) + expr(constructFrom(BindOptionalType, + ignoringImpCasts(anyOf(OptionalDereferenceMatcher, + StdMoveCallMatcher)))) .bind("expr"), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp index 1bd7abbad66d2..295955a971d7e 100644 --- a/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/ReturnConstRefFromParameterCheck.cpp @@ -31,21 +31,20 @@ void ReturnConstRefFromParameterCheck::registerMatchers(MatchFinder *Finder) { qualType(lValueReferenceType(pointee( qualType(isConstQualified())))) .bind("type"))), - hasDeclContext(functionDecl().bind("owner")), + hasDeclContext(functionDecl( + equalsBoundNode("func"), + hasReturnTypeLoc(loc(qualType( + hasCanonicalType(equalsBoundNode("type"))))))), unless(hasLifetimeBoundAttr())) .bind("param"))) .bind("dref")); - const auto Func = - functionDecl(equalsBoundNode("owner"), - hasReturnTypeLoc(loc( - qualType(hasCanonicalType(equalsBoundNode("type")))))) - .bind("func"); - Finder->addMatcher(returnStmt(hasReturnValue(DRef), hasAncestor(Func)), this); Finder->addMatcher( - returnStmt(hasReturnValue(ignoringParens(conditionalOperator( - eachOf(hasTrueExpression(DRef), hasFalseExpression(DRef)), - hasAncestor(Func))))), + returnStmt( + hasAncestor(functionDecl().bind("func")), + hasReturnValue(anyOf( + DRef, ignoringParens(conditionalOperator(eachOf( + hasTrueExpression(DRef), hasFalseExpression(DRef))))))), this); } diff --git a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h index 2d1570f7df8ab..e2fcccbfefb26 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/UncheckedOptionalAccessCheck.h @@ -12,7 +12,6 @@ #include "../ClangTidyCheck.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Analysis/FlowSensitive/Models/UncheckedOptionalAccessModel.h" -#include namespace clang::tidy::bugprone { @@ -26,8 +25,7 @@ class UncheckedOptionalAccessCheck : public ClangTidyCheck { public: UncheckedOptionalAccessCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - ModelOptions{ - Options.getLocalOrGlobal("IgnoreSmartPointerDereference", false)} {} + ModelOptions{Options.get("IgnoreSmartPointerDereference", false)} {} void registerMatchers(ast_matchers::MatchFinder *Finder) override; void check(const ast_matchers::MatchFinder::MatchResult &Result) override; bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp index 225e867c9b24f..d665c47d12bb4 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp @@ -277,7 +277,7 @@ ProTypeMemberInitCheck::ProTypeMemberInitCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IgnoreArrays(Options.get("IgnoreArrays", false)), - UseAssignment(Options.getLocalOrGlobal("UseAssignment", false)) {} + UseAssignment(Options.get("UseAssignment", false)) {} void ProTypeMemberInitCheck::registerMatchers(MatchFinder *Finder) { auto IsUserProvidedNonDelegatingConstructor = diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp index 7db9e29e8fd0e..8c386d5bc7945 100644 --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/RvalueReferenceParamNotMovedCheck.cpp @@ -119,11 +119,10 @@ void RvalueReferenceParamNotMovedCheck::check( RvalueReferenceParamNotMovedCheck::RvalueReferenceParamNotMovedCheck( StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - AllowPartialMove(Options.getLocalOrGlobal("AllowPartialMove", false)), - IgnoreUnnamedParams( - Options.getLocalOrGlobal("IgnoreUnnamedParams", false)), + AllowPartialMove(Options.get("AllowPartialMove", false)), + IgnoreUnnamedParams(Options.get("IgnoreUnnamedParams", false)), IgnoreNonDeducedTemplateTypes( - Options.getLocalOrGlobal("IgnoreNonDeducedTemplateTypes", false)) {} + Options.get("IgnoreNonDeducedTemplateTypes", false)) {} void RvalueReferenceParamNotMovedCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt index c919d49b42873..bab1167fb15ff 100644 --- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt +++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt @@ -36,6 +36,7 @@ add_clang_library(clangTidyModernizeModule STATIC UseEmplaceCheck.cpp UseEqualsDefaultCheck.cpp UseEqualsDeleteCheck.cpp + UseIntegerSignComparisonCheck.cpp UseNodiscardCheck.cpp UseNoexceptCheck.cpp UseNullptrCheck.cpp diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp index 1860759332063..fc46c72982fdc 100644 --- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp @@ -37,6 +37,7 @@ #include "UseEmplaceCheck.h" #include "UseEqualsDefaultCheck.h" #include "UseEqualsDeleteCheck.h" +#include "UseIntegerSignComparisonCheck.h" #include "UseNodiscardCheck.h" #include "UseNoexceptCheck.h" #include "UseNullptrCheck.h" @@ -76,6 +77,8 @@ class ModernizeModule : public ClangTidyModule { CheckFactories.registerCheck("modernize-pass-by-value"); CheckFactories.registerCheck( "modernize-use-designated-initializers"); + CheckFactories.registerCheck( + "modernize-use-integer-sign-comparison"); CheckFactories.registerCheck("modernize-use-ranges"); CheckFactories.registerCheck( "modernize-use-starts-ends-with"); diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp new file mode 100644 index 0000000000000..8f807bc0a96d5 --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.cpp @@ -0,0 +1,171 @@ +//===--- UseIntegerSignComparisonCheck.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 "UseIntegerSignComparisonCheck.h" +#include "clang/AST/Expr.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/Lex/Lexer.h" + +using namespace clang::ast_matchers; +using namespace clang::ast_matchers::internal; + +namespace clang::tidy::modernize { + +/// Find if the passed type is the actual "char" type, +/// not applicable to explicit "signed char" or "unsigned char" types. +static bool isActualCharType(const clang::QualType &Ty) { + using namespace clang; + const Type *DesugaredType = Ty->getUnqualifiedDesugaredType(); + if (const auto *BT = llvm::dyn_cast(DesugaredType)) + return (BT->getKind() == BuiltinType::Char_U || + BT->getKind() == BuiltinType::Char_S); + return false; +} + +namespace { +AST_MATCHER(clang::QualType, isActualChar) { + return clang::tidy::modernize::isActualCharType(Node); +} +} // namespace + +static BindableMatcher +intCastExpression(bool IsSigned, + const std::string &CastBindName = std::string()) { + // std::cmp_{} functions trigger a compile-time error if either LHS or RHS + // is a non-integer type, char, enum or bool + // (unsigned char/ signed char are Ok and can be used). + auto IntTypeExpr = expr(hasType(hasCanonicalType(qualType( + isInteger(), IsSigned ? isSignedInteger() : isUnsignedInteger(), + unless(isActualChar()), unless(booleanType()), unless(enumType()))))); + + const auto ImplicitCastExpr = + CastBindName.empty() ? implicitCastExpr(hasSourceExpression(IntTypeExpr)) + : implicitCastExpr(hasSourceExpression(IntTypeExpr)) + .bind(CastBindName); + + const auto CStyleCastExpr = cStyleCastExpr(has(ImplicitCastExpr)); + const auto StaticCastExpr = cxxStaticCastExpr(has(ImplicitCastExpr)); + const auto FunctionalCastExpr = cxxFunctionalCastExpr(has(ImplicitCastExpr)); + + return expr(anyOf(ImplicitCastExpr, CStyleCastExpr, StaticCastExpr, + FunctionalCastExpr)); +} + +static StringRef parseOpCode(BinaryOperator::Opcode Code) { + switch (Code) { + case BO_LT: + return "cmp_less"; + case BO_GT: + return "cmp_greater"; + case BO_LE: + return "cmp_less_equal"; + case BO_GE: + return "cmp_greater_equal"; + case BO_EQ: + return "cmp_equal"; + case BO_NE: + return "cmp_not_equal"; + default: + return ""; + } +} + +UseIntegerSignComparisonCheck::UseIntegerSignComparisonCheck( + StringRef Name, ClangTidyContext *Context) + : ClangTidyCheck(Name, Context), + IncludeInserter(Options.getLocalOrGlobal("IncludeStyle", + utils::IncludeSorter::IS_LLVM), + areDiagsSelfContained()) {} + +void UseIntegerSignComparisonCheck::storeOptions( + ClangTidyOptions::OptionMap &Opts) { + Options.store(Opts, "IncludeStyle", IncludeInserter.getStyle()); +} + +void UseIntegerSignComparisonCheck::registerMatchers(MatchFinder *Finder) { + const auto SignedIntCastExpr = intCastExpression(true, "sIntCastExpression"); + const auto UnSignedIntCastExpr = intCastExpression(false); + + // Flag all operators "==", "<=", ">=", "<", ">", "!=" + // that are used between signed/unsigned + const auto CompareOperator = + binaryOperator(hasAnyOperatorName("==", "<=", ">=", "<", ">", "!="), + hasOperands(SignedIntCastExpr, UnSignedIntCastExpr), + unless(isInTemplateInstantiation())) + .bind("intComparison"); + + Finder->addMatcher(CompareOperator, this); +} + +void UseIntegerSignComparisonCheck::registerPPCallbacks( + const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { + IncludeInserter.registerPreprocessor(PP); +} + +void UseIntegerSignComparisonCheck::check( + const MatchFinder::MatchResult &Result) { + const auto *SignedCastExpression = + Result.Nodes.getNodeAs("sIntCastExpression"); + assert(SignedCastExpression); + + // Ignore the match if we know that the signed int value is not negative. + Expr::EvalResult EVResult; + if (!SignedCastExpression->isValueDependent() && + SignedCastExpression->getSubExpr()->EvaluateAsInt(EVResult, + *Result.Context)) { + const llvm::APSInt SValue = EVResult.Val.getInt(); + if (SValue.isNonNegative()) + return; + } + + const auto *BinaryOp = + Result.Nodes.getNodeAs("intComparison"); + if (BinaryOp == nullptr) + return; + + const BinaryOperator::Opcode OpCode = BinaryOp->getOpcode(); + + const Expr *LHS = BinaryOp->getLHS()->IgnoreImpCasts(); + const Expr *RHS = BinaryOp->getRHS()->IgnoreImpCasts(); + if (LHS == nullptr || RHS == nullptr) + return; + const Expr *SubExprLHS = nullptr; + const Expr *SubExprRHS = nullptr; + SourceRange R1 = SourceRange(LHS->getBeginLoc()); + SourceRange R2 = SourceRange(BinaryOp->getOperatorLoc()); + SourceRange R3 = SourceRange(Lexer::getLocForEndOfToken( + RHS->getEndLoc(), 0, *Result.SourceManager, getLangOpts())); + if (const auto *LHSCast = llvm::dyn_cast(LHS)) { + SubExprLHS = LHSCast->getSubExpr(); + R1 = SourceRange(LHS->getBeginLoc(), + SubExprLHS->getBeginLoc().getLocWithOffset(-1)); + R2.setBegin(Lexer::getLocForEndOfToken( + SubExprLHS->getEndLoc(), 0, *Result.SourceManager, getLangOpts())); + } + if (const auto *RHSCast = llvm::dyn_cast(RHS)) { + SubExprRHS = RHSCast->getSubExpr(); + R2.setEnd(SubExprRHS->getBeginLoc().getLocWithOffset(-1)); + } + DiagnosticBuilder Diag = + diag(BinaryOp->getBeginLoc(), + "comparison between 'signed' and 'unsigned' integers"); + const std::string CmpNamespace = ("std::" + parseOpCode(OpCode)).str(); + const std::string CmpHeader = ""; + // Prefer modernize-use-integer-sign-comparison when C++20 is available! + Diag << FixItHint::CreateReplacement( + CharSourceRange(R1, SubExprLHS != nullptr), + llvm::Twine(CmpNamespace + "(").str()); + Diag << FixItHint::CreateReplacement(R2, ","); + Diag << FixItHint::CreateReplacement(CharSourceRange::getCharRange(R3), ")"); + + // If there is no include for cmp_{*} functions, we'll add it. + Diag << IncludeInserter.createIncludeInsertion( + Result.SourceManager->getFileID(BinaryOp->getBeginLoc()), CmpHeader); +} + +} // namespace clang::tidy::modernize diff --git a/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h new file mode 100644 index 0000000000000..a1074829d6eca --- /dev/null +++ b/clang-tools-extra/clang-tidy/modernize/UseIntegerSignComparisonCheck.h @@ -0,0 +1,42 @@ +//===--- UseIntegerSignComparisonCheck.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_MODERNIZE_USEINTEGERSIGNCOMPARISONCHECK_H +#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USEINTEGERSIGNCOMPARISONCHECK_H + +#include "../ClangTidyCheck.h" +#include "../utils/IncludeInserter.h" +#include "clang/ASTMatchers/ASTMatchFinder.h" + +namespace clang::tidy::modernize { + +/// Replace comparisons between signed and unsigned integers with their safe +/// C++20 ``std::cmp_*`` alternative, if available. +/// +/// For the user-facing documentation see: +/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-integer-sign-comparison.html +class UseIntegerSignComparisonCheck : public ClangTidyCheck { +public: + UseIntegerSignComparisonCheck(StringRef Name, ClangTidyContext *Context); + + void storeOptions(ClangTidyOptions::OptionMap &Opts) override; + void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP, + Preprocessor *ModuleExpanderPP) 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.CPlusPlus20; + } + +private: + utils::IncludeInserter IncludeInserter; +}; + +} // namespace clang::tidy::modernize + +#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USEINTEGERSIGNCOMPARISONCHECK_H diff --git a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp index dc6e0cf9c7d12..94cb7ec38087a 100644 --- a/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp +++ b/clang-tools-extra/clang-tidy/performance/InefficientVectorOperationCheck.cpp @@ -77,7 +77,7 @@ InefficientVectorOperationCheck::InefficientVectorOperationCheck( : ClangTidyCheck(Name, Context), VectorLikeClasses(utils::options::parseStringList( Options.get("VectorLikeClasses", "::std::vector"))), - EnableProto(Options.getLocalOrGlobal("EnableProto", false)) {} + EnableProto(Options.get("EnableProto", false)) {} void InefficientVectorOperationCheck::storeOptions( ClangTidyOptions::OptionMap &Opts) { diff --git a/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.h b/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.h index a5389d063f6cf..566e5ea637986 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.h +++ b/clang-tools-extra/clang-tidy/readability/RedundantAccessSpecifiersCheck.h @@ -21,8 +21,7 @@ class RedundantAccessSpecifiersCheck : public ClangTidyCheck { public: RedundantAccessSpecifiersCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - CheckFirstDeclaration( - Options.getLocalOrGlobal("CheckFirstDeclaration", false)) {} + CheckFirstDeclaration(Options.get("CheckFirstDeclaration", false)) {} bool isLanguageVersionSupported(const LangOptions &LangOpts) const override { return LangOpts.CPlusPlus; } diff --git a/clang-tools-extra/clang-tidy/readability/RedundantCastingCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantCastingCheck.cpp index b9ff0e81cbc52..4d5adbe02f525 100644 --- a/clang-tools-extra/clang-tidy/readability/RedundantCastingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/RedundantCastingCheck.cpp @@ -94,7 +94,7 @@ RedundantCastingCheck::RedundantCastingCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)), - IgnoreTypeAliases(Options.getLocalOrGlobal("IgnoreTypeAliases", false)) {} + IgnoreTypeAliases(Options.get("IgnoreTypeAliases", false)) {} void RedundantCastingCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "IgnoreMacros", IgnoreMacros); diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp index 88e4886cd0df9..9104723c7f1c0 100644 --- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp +++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp @@ -397,7 +397,7 @@ RenamerClangTidyCheck::RenamerClangTidyCheck(StringRef CheckName, ClangTidyContext *Context) : ClangTidyCheck(CheckName, Context), AggressiveDependentMemberLookup( - Options.getLocalOrGlobal("AggressiveDependentMemberLookup", false)) {} + Options.get("AggressiveDependentMemberLookup", false)) {} RenamerClangTidyCheck::~RenamerClangTidyCheck() = default; void RenamerClangTidyCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { diff --git a/clang-tools-extra/clangd/ClangdLSPServer.h b/clang-tools-extra/clangd/ClangdLSPServer.h index 597fd9de7ff68..f43734ec1ede3 100644 --- a/clang-tools-extra/clangd/ClangdLSPServer.h +++ b/clang-tools-extra/clangd/ClangdLSPServer.h @@ -73,6 +73,9 @@ class ClangdLSPServer : private ClangdServer::Callbacks, /// The destructor blocks on any outstanding background tasks. ~ClangdLSPServer(); + ClangdLSPServer(const ClangdLSPServer &other) = delete; + ClangdLSPServer &operator=(const ClangdLSPServer &other) = delete; + /// Run LSP server loop, communicating with the Transport provided in the /// constructor. This method must not be executed more than once. /// diff --git a/clang-tools-extra/clangd/CompileCommands.cpp b/clang-tools-extra/clangd/CompileCommands.cpp index fddfffe7523d9..207e4c3e6722c 100644 --- a/clang-tools-extra/clangd/CompileCommands.cpp +++ b/clang-tools-extra/clangd/CompileCommands.cpp @@ -458,20 +458,6 @@ llvm::ArrayRef ArgStripper::rulesFor(llvm::StringRef Arg) { PrevAlias[Self] = T; NextAlias[T] = Self; }; - // Also grab prefixes for each option, these are not fully exposed. - llvm::ArrayRef Prefixes[DriverID::LastOption]; - -#define PREFIX(NAME, VALUE) \ - static constexpr llvm::StringLiteral NAME##_init[] = VALUE; \ - static constexpr llvm::ArrayRef NAME( \ - NAME##_init, std::size(NAME##_init) - 1); -#define OPTION(PREFIX, PREFIXED_NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, \ - FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, \ - METAVAR, VALUES) \ - Prefixes[DriverID::OPT_##ID] = PREFIX; -#include "clang/Driver/Options.inc" -#undef OPTION -#undef PREFIX struct { DriverID ID; @@ -498,7 +484,9 @@ llvm::ArrayRef ArgStripper::rulesFor(llvm::StringRef Arg) { llvm::SmallVector Rules; // Iterate over each alias, to add rules for parsing it. for (unsigned A = ID; A != DriverID::OPT_INVALID; A = NextAlias[A]) { - if (!Prefixes[A].size()) // option groups. + llvm::SmallVector Prefixes; + DriverTable.appendOptionPrefixes(A, Prefixes); + if (Prefixes.empty()) // option groups. continue; auto Opt = DriverTable.getOption(A); // Exclude - and -foo pseudo-options. @@ -507,7 +495,7 @@ llvm::ArrayRef ArgStripper::rulesFor(llvm::StringRef Arg) { auto Modes = getModes(Opt); std::pair ArgCount = getArgCount(Opt); // Iterate over each spelling of the alias, e.g. -foo vs --foo. - for (StringRef Prefix : Prefixes[A]) { + for (StringRef Prefix : Prefixes) { llvm::SmallString<64> Buf(Prefix); Buf.append(Opt.getName()); llvm::StringRef Spelling = Result->try_emplace(Buf).first->getKey(); diff --git a/clang-tools-extra/clangd/HeuristicResolver.cpp b/clang-tools-extra/clangd/HeuristicResolver.cpp index 26d54200eeffd..9eb892e8e4a8e 100644 --- a/clang-tools-extra/clangd/HeuristicResolver.cpp +++ b/clang-tools-extra/clangd/HeuristicResolver.cpp @@ -118,6 +118,16 @@ const Type *resolveDeclsToType(const std::vector &Decls, return nullptr; } +TemplateName getReferencedTemplateName(const Type *T) { + if (const auto *TST = T->getAs()) { + return TST->getTemplateName(); + } + if (const auto *DTST = T->getAs()) { + return DTST->getTemplateName(); + } + return TemplateName(); +} + // Helper function for HeuristicResolver::resolveDependentMember() // which takes a possibly-dependent type `T` and heuristically // resolves it to a CXXRecordDecl in which we can try name lookup. @@ -142,12 +152,12 @@ CXXRecordDecl *HeuristicResolverImpl::resolveTypeToRecordDecl(const Type *T) { if (!T) return nullptr; - const auto *TST = T->getAs(); - if (!TST) + TemplateName TN = getReferencedTemplateName(T); + if (TN.isNull()) return nullptr; - const ClassTemplateDecl *TD = dyn_cast_or_null( - TST->getTemplateName().getAsTemplateDecl()); + const ClassTemplateDecl *TD = + dyn_cast_or_null(TN.getAsTemplateDecl()); if (!TD) return nullptr; diff --git a/clang-tools-extra/clangd/ModulesBuilder.cpp b/clang-tools-extra/clangd/ModulesBuilder.cpp index 29508901f85bb..bee31fe51555e 100644 --- a/clang-tools-extra/clangd/ModulesBuilder.cpp +++ b/clang-tools-extra/clangd/ModulesBuilder.cpp @@ -199,7 +199,7 @@ bool IsModuleFileUpToDate(PathRef ModuleFilePath, SourceManager SourceMgr(*Diags, FileMgr); - HeaderSearch HeaderInfo(HSOpts, SourceMgr, *Diags, LangOpts, + HeaderSearch HeaderInfo(std::move(HSOpts), SourceMgr, *Diags, LangOpts, /*Target=*/nullptr); TrivialModuleLoader ModuleLoader; diff --git a/clang-tools-extra/clangd/ParsedAST.h b/clang-tools-extra/clangd/ParsedAST.h index 63e564bd68a78..8d9d1e6456926 100644 --- a/clang-tools-extra/clangd/ParsedAST.h +++ b/clang-tools-extra/clangd/ParsedAST.h @@ -59,6 +59,9 @@ class ParsedAST { ~ParsedAST(); + ParsedAST(const ParsedAST &Other) = delete; + ParsedAST &operator=(const ParsedAST &Other) = delete; + /// Note that the returned ast will not contain decls from the preamble that /// were not deserialized during parsing. Clients should expect only decls /// from the main file to be in the AST. diff --git a/clang-tools-extra/clangd/TUScheduler.cpp b/clang-tools-extra/clangd/TUScheduler.cpp index 71548b59cc308..035e5e63d8fbb 100644 --- a/clang-tools-extra/clangd/TUScheduler.cpp +++ b/clang-tools-extra/clangd/TUScheduler.cpp @@ -411,6 +411,9 @@ class PreambleThrottlerRequest { if (Throttler) Throttler->release(ID); } + PreambleThrottlerRequest(const PreambleThrottlerRequest &) = delete; + PreambleThrottlerRequest & + operator=(const PreambleThrottlerRequest &) = delete; private: PreambleThrottler::RequestID ID; @@ -621,7 +624,8 @@ class ASTWorker { AsyncTaskRunner *Tasks, Semaphore &Barrier, const TUScheduler::Options &Opts, ParsingCallbacks &Callbacks); ~ASTWorker(); - + ASTWorker(const ASTWorker &other) = delete; + ASTWorker &operator=(const ASTWorker &other) = delete; void update(ParseInputs Inputs, WantDiagnostics, bool ContentChanged); void runWithAST(llvm::StringRef Name, diff --git a/clang-tools-extra/clangd/TUScheduler.h b/clang-tools-extra/clangd/TUScheduler.h index fb936d46bbcf7..d0da20310a8b2 100644 --- a/clang-tools-extra/clangd/TUScheduler.h +++ b/clang-tools-extra/clangd/TUScheduler.h @@ -242,6 +242,9 @@ class TUScheduler { std::unique_ptr ASTCallbacks = nullptr); ~TUScheduler(); + TUScheduler(const TUScheduler &other) = delete; + TUScheduler &operator=(const TUScheduler &other) = delete; + struct FileStats { std::size_t UsedBytesAST = 0; std::size_t UsedBytesPreamble = 0; diff --git a/clang-tools-extra/clangd/index/MemIndex.h b/clang-tools-extra/clangd/index/MemIndex.h index 8f390c5028dc4..fb1052b0c7ca8 100644 --- a/clang-tools-extra/clangd/index/MemIndex.h +++ b/clang-tools-extra/clangd/index/MemIndex.h @@ -97,7 +97,7 @@ class MemIndex : public SymbolIndex { // Set of files which were used during this index build. llvm::StringSet<> Files; // Contents of the index (symbols, references, etc.) - IndexContents IdxContents; + IndexContents IdxContents = IndexContents::None; std::shared_ptr KeepAlive; // poor man's move-only std::any // Size of memory retained by KeepAlive. size_t BackingDataSize = 0; diff --git a/clang-tools-extra/clangd/index/SymbolCollector.cpp b/clang-tools-extra/clangd/index/SymbolCollector.cpp index 81125dbb1aeaf..6d0af20e31260 100644 --- a/clang-tools-extra/clangd/index/SymbolCollector.cpp +++ b/clang-tools-extra/clangd/index/SymbolCollector.cpp @@ -550,9 +550,14 @@ bool SymbolCollector::shouldCollectSymbol(const NamedDecl &ND, // Avoid indexing internal symbols in protobuf generated headers. if (isPrivateProtoDecl(ND)) return false; + + // System headers that end with `intrin.h` likely contain useful symbols. if (!Opts.CollectReserved && (hasReservedName(ND) || hasReservedScope(*ND.getDeclContext())) && - ASTCtx.getSourceManager().isInSystemHeader(ND.getLocation())) + ASTCtx.getSourceManager().isInSystemHeader(ND.getLocation()) && + !ASTCtx.getSourceManager() + .getFilename(ND.getLocation()) + .ends_with("intrin.h")) return false; return true; diff --git a/clang-tools-extra/clangd/index/dex/Dex.h b/clang-tools-extra/clangd/index/dex/Dex.h index 20c0503d19b97..502f597d81ef0 100644 --- a/clang-tools-extra/clangd/index/dex/Dex.h +++ b/clang-tools-extra/clangd/index/dex/Dex.h @@ -146,7 +146,9 @@ class Dex : public SymbolIndex { // Set of files which were used during this index build. llvm::StringSet<> Files; // Contents of the index (symbols, references, etc.) - IndexContents IdxContents; + // This is only populated if `Files` is, which applies to some but not all + // consumers of this class. + IndexContents IdxContents = IndexContents::None; // Size of memory retained by KeepAlive. size_t BackingDataSize = 0; }; diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp index 3b378153eafd5..d84e501b87ce7 100644 --- a/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp +++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractVariable.cpp @@ -49,7 +49,8 @@ class ExtractionContext { llvm::StringRef VarName) const; // Generate Replacement for declaring the selected Expr as a new variable tooling::Replacement insertDeclaration(llvm::StringRef VarName, - SourceRange InitChars) const; + SourceRange InitChars, + bool AddSemicolon) const; private: bool Extractable = false; @@ -252,7 +253,8 @@ ExtractionContext::replaceWithVar(SourceRange Chars, // returns the Replacement for declaring a new variable storing the extraction tooling::Replacement ExtractionContext::insertDeclaration(llvm::StringRef VarName, - SourceRange InitializerChars) const { + SourceRange InitializerChars, + bool AddSemicolon) const { llvm::StringRef ExtractionCode = toSourceCode(SM, InitializerChars); const SourceLocation InsertionLoc = toHalfOpenFileRange(SM, Ctx.getLangOpts(), @@ -260,7 +262,9 @@ ExtractionContext::insertDeclaration(llvm::StringRef VarName, ->getBegin(); std::string ExtractedVarDecl = printType(VarType, ExprNode->getDeclContext(), VarName) + " = " + - ExtractionCode.str() + "; "; + ExtractionCode.str(); + if (AddSemicolon) + ExtractedVarDecl += "; "; return tooling::Replacement(SM, InsertionLoc, 0, ExtractedVarDecl); } @@ -419,12 +423,10 @@ const SelectionTree::Node *getCallExpr(const SelectionTree::Node *DeclRef) { // Returns true if Inner (which is a direct child of Outer) is appearing as // a statement rather than an expression whose value can be used. -bool childExprIsStmt(const Stmt *Outer, const Expr *Inner) { +bool childExprIsDisallowedStmt(const Stmt *Outer, const Expr *Inner) { if (!Outer || !Inner) return false; // Exclude the most common places where an expr can appear but be unused. - if (llvm::isa(Outer)) - return true; if (llvm::isa(Outer)) return true; // Control flow statements use condition etc, but not the body. @@ -476,12 +478,9 @@ bool eligibleForExtraction(const SelectionTree::Node *N) { const auto *Parent = OuterImplicit.Parent; if (!Parent) return false; - // We don't want to extract expressions used as statements, that would leave - // a `placeholder;` around that has no effect. - // Unfortunately because the AST doesn't have ExprStmt, we have to check in - // this roundabout way. - if (childExprIsStmt(Parent->ASTNode.get(), - OuterImplicit.ASTNode.get())) + // Filter non-applicable expression statements. + if (childExprIsDisallowedStmt(Parent->ASTNode.get(), + OuterImplicit.ASTNode.get())) return false; std::function IsFullySelected = @@ -516,6 +515,12 @@ bool eligibleForExtraction(const SelectionTree::Node *N) { return false; } + // If e.g. a capture clause was selected, the target node is the lambda + // expression. We only want to offer the extraction if the entire lambda + // expression was selected. + if (llvm::isa(E)) + return N->Selected == SelectionTree::Complete; + // The same logic as for assignments applies to initializations. // However, we do allow extracting the RHS of an init capture, as it is // a valid use case to move non-trivial expressions out of the capture clause. @@ -599,10 +604,24 @@ Expected ExtractVariable::apply(const Selection &Inputs) { // FIXME: get variable name from user or suggest based on type std::string VarName = "placeholder"; SourceRange Range = Target->getExtractionChars(); - // insert new variable declaration - if (auto Err = Result.add(Target->insertDeclaration(VarName, Range))) + + const SelectionTree::Node &OuterImplicit = + Target->getExprNode()->outerImplicit(); + assert(OuterImplicit.Parent); + bool IsExprStmt = llvm::isa_and_nonnull( + OuterImplicit.Parent->ASTNode.get()); + + // insert new variable declaration. add a semicolon if and only if + // we are not dealing with an expression statement, which already has + // a semicolon that stays where it is, as it's not part of the range. + if (auto Err = + Result.add(Target->insertDeclaration(VarName, Range, !IsExprStmt))) return std::move(Err); - // replace expression with variable name + + // replace expression with variable name, unless it's an expression statement, + // in which case we remove it. + if (IsExprStmt) + VarName.clear(); if (auto Err = Result.add(Target->replaceWithVar(Range, VarName))) return std::move(Err); return Effect::mainFileEdit(Inputs.AST->getSourceManager(), diff --git a/clang-tools-extra/clangd/support/DirectiveTree.cpp b/clang-tools-extra/clangd/support/DirectiveTree.cpp index d25da111681af..7ea08add7a107 100644 --- a/clang-tools-extra/clangd/support/DirectiveTree.cpp +++ b/clang-tools-extra/clangd/support/DirectiveTree.cpp @@ -328,6 +328,9 @@ class Preprocessor { Preprocessor(const TokenStream &In, TokenStream &Out) : In(In), Out(Out) {} ~Preprocessor() { Out.finalize(); } + Preprocessor(const Preprocessor &other) = delete; + Preprocessor &operator=(const Preprocessor &other) = delete; + void walk(const DirectiveTree &T) { for (const auto &C : T.Chunks) std::visit(*this, C); diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp index 3220a5a6a9825..fc54f89f4941e 100644 --- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp +++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp @@ -842,6 +842,8 @@ TEST_F(TargetDeclTest, OverloadExpr) { } TEST_F(TargetDeclTest, DependentExprs) { + Flags.push_back("--std=c++20"); + // Heuristic resolution of method of dependent field Code = R"cpp( struct A { void foo() {} }; @@ -962,6 +964,21 @@ TEST_F(TargetDeclTest, DependentExprs) { }; )cpp"; EXPECT_DECLS("MemberExpr", "void find()"); + + // Base expression is the type of a non-type template parameter + // which is deduced using CTAD. + Code = R"cpp( + template + struct Waldo { + const int found = N; + }; + + template + int test() { + return W.[[found]]; + } + )cpp"; + EXPECT_DECLS("CXXDependentScopeMemberExpr", "const int found = N"); } TEST_F(TargetDeclTest, DependentTypes) { diff --git a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp index 30b9b1902aa9c..1ec51d862d0a6 100644 --- a/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp +++ b/clang-tools-extra/clangd/unittests/SemanticHighlightingTests.cpp @@ -1092,6 +1092,13 @@ sizeof...($TemplateParameter[[Elements]]); $Field_dependentName[[waldo]]; } }; + )cpp", + // Pointer-to-member with nested-name-specifiers + R"cpp( + struct $Class_def[[Outer]] { + struct $Class_def[[Inner]] {}; + }; + using $Typedef_decl[[Alias]] = void ($Class[[Outer]]::$Class[[Inner]]:: *)(); )cpp"}; for (const auto &TestCase : TestCases) // Mask off scope modifiers to keep the tests manageable. diff --git a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp index e8088cb37fa51..7a9703c744e93 100644 --- a/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp +++ b/clang-tools-extra/clangd/unittests/SymbolCollectorTests.cpp @@ -2111,6 +2111,20 @@ TEST_F(SymbolCollectorTest, Reserved) { EXPECT_THAT(Symbols, IsEmpty()); } +TEST_F(SymbolCollectorTest, ReservedSymbolInIntrinsicHeader) { + const char *Header = R"cpp( + #pragma once + void __foo(); + )cpp"; + + TestHeaderName = "xintrin.h"; + TestHeaderURI = URI::create(testPath(TestHeaderName)).toString(); + InMemoryFileSystem = new llvm::vfs::InMemoryFileSystem; + CollectorOpts.FallbackDir = testRoot(); + runSymbolCollector("#pragma GCC system_header\n" + std::string(Header), ""); + EXPECT_THAT(Symbols, UnorderedElementsAre(qName("__foo"))); +} + TEST_F(SymbolCollectorTest, Concepts) { const char *Header = R"cpp( template diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp index d393c72974d44..7d824d659ad2c 100644 --- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp +++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp @@ -1019,6 +1019,15 @@ TEST(LocateSymbol, All) { void *Value; void *getPointer() const { return Info::get^Pointer(Value); } }; + )cpp", + R"cpp(// Deducing this + struct S { + int bar(this S&); + }; + void foo() { + S [[waldo]]; + int x = wa^ldo.bar(); + } )cpp"}; for (const char *Test : Tests) { Annotations T(Test); @@ -1035,6 +1044,7 @@ TEST(LocateSymbol, All) { TU.Code = std::string(T.code()); TU.ExtraArgs.push_back("-xobjective-c++"); + TU.ExtraArgs.push_back("-std=c++23"); auto AST = TU.build(); auto Results = locateSymbolAt(AST, T.point()); diff --git a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp index 656b62c9a1f4e..552e693c0363a 100644 --- a/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp +++ b/clang-tools-extra/clangd/unittests/tweaks/ExtractVariableTests.cpp @@ -151,8 +151,8 @@ TEST_F(ExtractVariableTest, Test) { // Variable DeclRefExpr a = [[b]]; a = [[xyz()]]; - // statement expression - [[xyz()]]; + // expression statement of type void + [[v()]]; while (a) [[++a]]; // label statement @@ -493,6 +493,16 @@ TEST_F(ExtractVariableTest, Test) { a = a + 1; } })cpp"}, + {R"cpp( + int func() { return 0; } + int main() { + [[func()]]; + })cpp", + R"cpp( + int func() { return 0; } + int main() { + auto placeholder = func(); + })cpp"}, {R"cpp( template auto call(T t) { return t(); } diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst index e00f86f7d0144..6803842106791 100644 --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -136,10 +136,16 @@ New checks Gives warnings for tagged unions, where the number of tags is different from the number of data members inside the union. +- New :doc:`modernize-use-integer-sign-comparison + ` check. + + Replace comparisons between signed and unsigned integers with their safe + C++20 ``std::cmp_*`` alternative, if available. + - New :doc:`portability-template-virtual-member-function ` check. - Finds cases when an uninstantiated virtual member function in a template class + Finds cases when an uninstantiated virtual member function in a template class causes cross-compiler incompatibility. New check aliases @@ -176,6 +182,10 @@ Changes in existing checks ` check by fixing a crash when determining if an ``enable_if[_t]`` was found. +- Improved :doc:`bugprone-optional-value-conversion + ` to support detecting + conversion directly by ``std::make_unique`` and ``std::make_shared``. + - Improved :doc:`bugprone-posix-return ` check to support integer literals as LHS and posix call as RHS of comparison. @@ -183,8 +193,8 @@ Changes in existing checks - Improved :doc:`bugprone-return-const-ref-from-parameter ` check to diagnose potential dangling references when returning a ``const &`` parameter - by using the conditional operator ``cond ? var1 : var2`` and no longer giving - false positives for functions which contain lambda and ignore parameters + by using the conditional operator ``cond ? var1 : var2`` and fixing false + positives for functions which contain lambda and ignore parameters with ``[[clang::lifetimebound]]`` attribute. - Improved :doc:`bugprone-sizeof-expression diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.PureVirtualCall.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.PureVirtualCall.rst deleted file mode 100644 index 9fab628b80d44..0000000000000 --- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.PureVirtualCall.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. title:: clang-tidy - clang-analyzer-cplusplus.PureVirtualCall - -clang-analyzer-cplusplus.PureVirtualCall -======================================== - -Check pure virtual function calls during construction/destruction. - -The clang-analyzer-cplusplus.PureVirtualCall check is an alias of -Clang Static Analyzer cplusplus.PureVirtualCall. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.SelfAssignment.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.SelfAssignment.rst new file mode 100644 index 0000000000000..62e300660828b --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/cplusplus.SelfAssignment.rst @@ -0,0 +1,13 @@ +.. title:: clang-tidy - clang-analyzer-cplusplus.SelfAssignment +.. meta:: + :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#cplusplus-selfassignment + +clang-analyzer-cplusplus.SelfAssignment +======================================= + +Checks C++ copy and move assignment operators for self assignment. + +The `clang-analyzer-cplusplus.SelfAssignment` check is an alias, please see +`Clang Static Analyzer Available Checkers +`_ +for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.OSObjectCStyleCast.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.OSObjectCStyleCast.rst deleted file mode 100644 index c2fef59f56894..0000000000000 --- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/optin.osx.OSObjectCStyleCast.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. title:: clang-tidy - clang-analyzer-optin.osx.OSObjectCStyleCast - -clang-analyzer-optin.osx.OSObjectCStyleCast -=========================================== - -Checker for C-style casts of OSObjects. - -The clang-analyzer-optin.osx.OSObjectCStyleCast check is an alias of -Clang Static Analyzer optin.osx.OSObjectCStyleCast. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.MIG.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.MIG.rst deleted file mode 100644 index a7b8a1cfb14cd..0000000000000 --- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.MIG.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. title:: clang-tidy - clang-analyzer-osx.MIG - -clang-analyzer-osx.MIG -====================== - -Find violations of the Mach Interface Generator calling convention. - -The clang-analyzer-osx.MIG check is an alias of -Clang Static Analyzer osx.MIG. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.OSObjectRetainCount.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.OSObjectRetainCount.rst deleted file mode 100644 index c32982d407c28..0000000000000 --- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/osx.OSObjectRetainCount.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. title:: clang-tidy - clang-analyzer-osx.OSObjectRetainCount - -clang-analyzer-osx.OSObjectRetainCount -====================================== - -Check for leaks and improper reference count management for OSObject. - -The clang-analyzer-osx.OSObjectRetainCount check is an alias of -Clang Static Analyzer osx.OSObjectRetainCount. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.PutenvStackArray.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.PutenvStackArray.rst index 0a5feff8d3ca8..5858078246d9b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.PutenvStackArray.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.PutenvStackArray.rst @@ -1,10 +1,17 @@ .. title:: clang-tidy - clang-analyzer-security.PutenvStackArray +.. meta:: + :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#security-putenvstackarray-c clang-analyzer-security.PutenvStackArray ======================================== -Finds calls to the function 'putenv' which pass a pointer to an automatic -(stack-allocated) array as the argument. +Finds calls to the putenv function which pass a pointer to a stack-allocated +(automatic) array as the argument. Function putenv does not copy the passed +string, only a pointer to the data is stored and this data can be read even by +other threads. Content of a stack-allocated array is likely to be overwritten +after exiting from the function. -The clang-analyzer-security.PutenvStackArray check is an alias of -Clang Static Analyzer security.PutenvStackArray. +The `clang-analyzer-security.PutenvStackArray` check is an alias, please see +`Clang Static Analyzer Available Checkers +`_ +for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.SetgidSetuidOrder.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.SetgidSetuidOrder.rst index 82f22b11f77fb..b3ba78597a5ba 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.SetgidSetuidOrder.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/security.SetgidSetuidOrder.rst @@ -1,10 +1,18 @@ .. title:: clang-tidy - clang-analyzer-security.SetgidSetuidOrder +.. meta:: + :http-equiv=refresh: 5;URL=https://clang.llvm.org/docs/analyzer/checkers.html#security-setgidsetuidorder-c clang-analyzer-security.SetgidSetuidOrder ========================================= -Warn on possible reversed order of 'setgid(getgid()))' and 'setuid(getuid())' -(CERT: POS36-C). +The checker checks for sequences of ``setuid(getuid())`` and ``setgid(getgid())`` +calls (in this order). If such a sequence is found and there is no other +privilege-changing function call (``seteuid``, ``setreuid``, ``setresuid`` and +the GID versions of these) in between, a warning is generated. The checker finds +only exactly ``setuid(getuid())`` calls (and the GID versions), not for example +if the result of ``getuid()`` is stored in a variable. -The clang-analyzer-security.SetgidSetuidOrder check is an alias of -Clang Static Analyzer security.SetgidSetuidOrder. +The `clang-analyzer-security.SetgidSetuidOrder` check is an alias, please see +`Clang Static Analyzer Available Checkers +`_ +for more information. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/valist.CopyToSelf.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/valist.CopyToSelf.rst deleted file mode 100644 index d0c82abd81901..0000000000000 --- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/valist.CopyToSelf.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. title:: clang-tidy - clang-analyzer-valist.CopyToSelf - -clang-analyzer-valist.CopyToSelf -================================ - -Check for va_lists which are copied onto itself. - -The clang-analyzer-valist.CopyToSelf check is an alias of -Clang Static Analyzer valist.CopyToSelf. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/valist.Uninitialized.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/valist.Uninitialized.rst deleted file mode 100644 index 98b5dd023254a..0000000000000 --- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/valist.Uninitialized.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. title:: clang-tidy - clang-analyzer-valist.Uninitialized - -clang-analyzer-valist.Uninitialized -=================================== - -Check for usages of uninitialized (or already released) va_lists. - -The clang-analyzer-valist.Uninitialized check is an alias of -Clang Static Analyzer valist.Uninitialized. diff --git a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/valist.Unterminated.rst b/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/valist.Unterminated.rst deleted file mode 100644 index 85e21c5721063..0000000000000 --- a/clang-tools-extra/docs/clang-tidy/checks/clang-analyzer/valist.Unterminated.rst +++ /dev/null @@ -1,9 +0,0 @@ -.. title:: clang-tidy - clang-analyzer-valist.Unterminated - -clang-analyzer-valist.Unterminated -================================== - -Check for va_lists which are not released by a va_end call. - -The clang-analyzer-valist.Unterminated check is an alias of -Clang Static Analyzer valist.Unterminated. diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst index d731b13fc0df4..4d8853a0f6d86 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/list.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst @@ -115,8 +115,8 @@ Clang-Tidy Checks :doc:`bugprone-multiple-new-in-one-expression `, :doc:`bugprone-multiple-statement-macro `, :doc:`bugprone-no-escape `, - :doc:`bugprone-nondeterministic-pointer-iteration-order `, :doc:`bugprone-non-zero-enum-to-bool-conversion `, + :doc:`bugprone-nondeterministic-pointer-iteration-order `, :doc:`bugprone-not-null-terminated-result `, "Yes" :doc:`bugprone-optional-value-conversion `, "Yes" :doc:`bugprone-parent-virtual-call `, "Yes" @@ -301,6 +301,7 @@ Clang-Tidy Checks :doc:`modernize-use-emplace `, "Yes" :doc:`modernize-use-equals-default `, "Yes" :doc:`modernize-use-equals-delete `, "Yes" + :doc:`modernize-use-integer-sign-comparison `, "Yes" :doc:`modernize-use-nodiscard `, "Yes" :doc:`modernize-use-noexcept `, "Yes" :doc:`modernize-use-nullptr `, "Yes" @@ -458,7 +459,7 @@ Check aliases :doc:`clang-analyzer-cplusplus.NewDelete `, `Clang Static Analyzer cplusplus.NewDelete `_, :doc:`clang-analyzer-cplusplus.NewDeleteLeaks `, `Clang Static Analyzer cplusplus.NewDeleteLeaks `_, :doc:`clang-analyzer-cplusplus.PlacementNew `, `Clang Static Analyzer cplusplus.PlacementNew `_, - :doc:`clang-analyzer-cplusplus.PureVirtualCall `, Clang Static Analyzer cplusplus.PureVirtualCall, + :doc:`clang-analyzer-cplusplus.SelfAssignment `, `Clang Static Analyzer cplusplus.SelfAssignment `_, :doc:`clang-analyzer-cplusplus.StringChecker `, `Clang Static Analyzer cplusplus.StringChecker `_, :doc:`clang-analyzer-deadcode.DeadStores `, `Clang Static Analyzer deadcode.DeadStores `_, :doc:`clang-analyzer-fuchsia.HandleChecker `, `Clang Static Analyzer fuchsia.HandleChecker `_, @@ -471,7 +472,6 @@ Check aliases :doc:`clang-analyzer-optin.cplusplus.UninitializedObject `, `Clang Static Analyzer optin.cplusplus.UninitializedObject `_, :doc:`clang-analyzer-optin.cplusplus.VirtualCall `, `Clang Static Analyzer optin.cplusplus.VirtualCall `_, :doc:`clang-analyzer-optin.mpi.MPI-Checker `, `Clang Static Analyzer optin.mpi.MPI-Checker `_, - :doc:`clang-analyzer-optin.osx.OSObjectCStyleCast `, Clang Static Analyzer optin.osx.OSObjectCStyleCast, :doc:`clang-analyzer-optin.osx.cocoa.localizability.EmptyLocalizationContextChecker `, `Clang Static Analyzer optin.osx.cocoa.localizability.EmptyLocalizationContextChecker `_, :doc:`clang-analyzer-optin.osx.cocoa.localizability.NonLocalizedStringChecker `, `Clang Static Analyzer optin.osx.cocoa.localizability.NonLocalizedStringChecker `_, :doc:`clang-analyzer-optin.performance.GCDAntipattern `, `Clang Static Analyzer optin.performance.GCDAntipattern `_, @@ -479,9 +479,7 @@ Check aliases :doc:`clang-analyzer-optin.portability.UnixAPI `, `Clang Static Analyzer optin.portability.UnixAPI `_, :doc:`clang-analyzer-optin.taint.TaintedAlloc `, `Clang Static Analyzer optin.taint.TaintedAlloc `_, :doc:`clang-analyzer-osx.API `, `Clang Static Analyzer osx.API `_, - :doc:`clang-analyzer-osx.MIG `, Clang Static Analyzer osx.MIG, :doc:`clang-analyzer-osx.NumberObjectConversion `, `Clang Static Analyzer osx.NumberObjectConversion `_, - :doc:`clang-analyzer-osx.OSObjectRetainCount `, Clang Static Analyzer osx.OSObjectRetainCount, :doc:`clang-analyzer-osx.ObjCProperty `, `Clang Static Analyzer osx.ObjCProperty `_, :doc:`clang-analyzer-osx.SecKeychainAPI `, `Clang Static Analyzer osx.SecKeychainAPI `_, :doc:`clang-analyzer-osx.cocoa.AtSync `, `Clang Static Analyzer osx.cocoa.AtSync `_, @@ -508,8 +506,8 @@ Check aliases :doc:`clang-analyzer-osx.coreFoundation.containers.OutOfBounds `, `Clang Static Analyzer osx.coreFoundation.containers.OutOfBounds `_, :doc:`clang-analyzer-osx.coreFoundation.containers.PointerSizedValues `, `Clang Static Analyzer osx.coreFoundation.containers.PointerSizedValues `_, :doc:`clang-analyzer-security.FloatLoopCounter `, `Clang Static Analyzer security.FloatLoopCounter `_, - :doc:`clang-analyzer-security.PutenvStackArray `, Clang Static Analyzer security.PutenvStackArray, - :doc:`clang-analyzer-security.SetgidSetuidOrder `, Clang Static Analyzer security.SetgidSetuidOrder, + :doc:`clang-analyzer-security.PutenvStackArray `, `Clang Static Analyzer security.PutenvStackArray `_, + :doc:`clang-analyzer-security.SetgidSetuidOrder `, `Clang Static Analyzer security.SetgidSetuidOrder `_, :doc:`clang-analyzer-security.cert.env.InvalidPtr `, `Clang Static Analyzer security.cert.env.InvalidPtr `_, :doc:`clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling `, `Clang Static Analyzer security.insecureAPI.DeprecatedOrUnsafeBufferHandling `_, :doc:`clang-analyzer-security.insecureAPI.UncheckedReturn `, `Clang Static Analyzer security.insecureAPI.UncheckedReturn `_, @@ -535,9 +533,6 @@ Check aliases :doc:`clang-analyzer-unix.Vfork `, `Clang Static Analyzer unix.Vfork `_, :doc:`clang-analyzer-unix.cstring.BadSizeArg `, `Clang Static Analyzer unix.cstring.BadSizeArg `_, :doc:`clang-analyzer-unix.cstring.NullArg `, `Clang Static Analyzer unix.cstring.NullArg `_, - :doc:`clang-analyzer-valist.CopyToSelf `, Clang Static Analyzer valist.CopyToSelf, - :doc:`clang-analyzer-valist.Uninitialized `, Clang Static Analyzer valist.Uninitialized, - :doc:`clang-analyzer-valist.Unterminated `, Clang Static Analyzer valist.Unterminated, :doc:`clang-analyzer-webkit.NoUncountedMemberChecker `, `Clang Static Analyzer webkit.NoUncountedMemberChecker `_, :doc:`clang-analyzer-webkit.RefCntblBaseVirtualDtor `, `Clang Static Analyzer webkit.RefCntblBaseVirtualDtor `_, :doc:`clang-analyzer-webkit.UncountedLambdaCapturesChecker `, `Clang Static Analyzer webkit.UncountedLambdaCapturesChecker `_, diff --git a/clang-tools-extra/docs/clang-tidy/checks/misc/unused-parameters.rst b/clang-tools-extra/docs/clang-tidy/checks/misc/unused-parameters.rst index 87b75579d97a7..9321f651fd705 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/misc/unused-parameters.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/misc/unused-parameters.rst @@ -35,13 +35,13 @@ Options .. option:: StrictMode - When `false` (default value), the check will ignore trivially unused parameters, - i.e. when the corresponding function has an empty body (and in case of - constructors - no constructor initializers). When the function body is empty, - an unused parameter is unlikely to be unnoticed by a human reader, and - there's basically no place for a bug to hide. + When `false` (default value), the check will ignore trivially unused parameters, + i.e. when the corresponding function has an empty body (and in case of + constructors - no constructor initializers). When the function body is empty, + an unused parameter is unlikely to be unnoticed by a human reader, and + there's basically no place for a bug to hide. .. option:: IgnoreVirtual - Determines whether virtual method parameters should be inspected. - Set to `true` to ignore them. Default is `false`. + Determines whether virtual method parameters should be inspected. + Set to `true` to ignore them. Default is `false`. diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst new file mode 100644 index 0000000000000..7e2c13b782694 --- /dev/null +++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-integer-sign-comparison.rst @@ -0,0 +1,36 @@ +.. title:: clang-tidy - modernize-use-integer-sign-comparison + +modernize-use-integer-sign-comparison +===================================== + +Replace comparisons between signed and unsigned integers with their safe +C++20 ``std::cmp_*`` alternative, if available. + +The check provides a replacement only for C++20 or later, otherwise +it highlights the problem and expects the user to fix it manually. + +Examples of fixes created by the check: + +.. code-block:: c++ + + unsigned int func(int a, unsigned int b) { + return a == b; + } + +becomes + +.. code-block:: c++ + + #include + + unsigned int func(int a, unsigned int b) { + return std::cmp_equal(a, b); + } + +Options +------- + +.. option:: IncludeStyle + + A string specifying which include-style is used, `llvm` or `google`. + Default is `llvm`. diff --git a/clang-tools-extra/docs/clang-tidy/index.rst b/clang-tools-extra/docs/clang-tidy/index.rst index a4233d5d8e269..f053e57e8d4c8 100644 --- a/clang-tools-extra/docs/clang-tidy/index.rst +++ b/clang-tools-extra/docs/clang-tidy/index.rst @@ -9,7 +9,7 @@ See also: .. toctree:: :maxdepth: 1 - The list of clang-tidy checks + List of Clang-Tidy Checks Clang-tidy IDE/Editor Integrations Getting Involved External Clang-Tidy Examples @@ -21,7 +21,7 @@ static analysis. :program:`clang-tidy` is modular and provides a convenient interface for writing new checks. -Using clang-tidy +Using Clang-Tidy ================ :program:`clang-tidy` is a `LibTooling`_-based tool, and it's easier to work diff --git a/clang-tools-extra/modularize/ModuleAssistant.cpp b/clang-tools-extra/modularize/ModuleAssistant.cpp index 5c11ffdb8589d..c7259d70bd58f 100644 --- a/clang-tools-extra/modularize/ModuleAssistant.cpp +++ b/clang-tools-extra/modularize/ModuleAssistant.cpp @@ -46,6 +46,8 @@ class Module { public: Module(llvm::StringRef Name, bool Problem); ~Module(); + Module(const Module &other) = delete; + Module &operator=(const Module &other) = delete; bool output(llvm::raw_fd_ostream &OS, int Indent); Module *findSubModule(llvm::StringRef SubName); diff --git a/clang-tools-extra/test/clang-doc/templates.cpp b/clang-tools-extra/test/clang-doc/templates.cpp index 4d4a25b8d3b82..5229063f7ee23 100644 --- a/clang-tools-extra/test/clang-doc/templates.cpp +++ b/clang-tools-extra/test/clang-doc/templates.cpp @@ -1,76 +1,157 @@ // RUN: rm -rf %t // RUN: mkdir %t -// RUN: echo "" > %t/compile_flags.txt -// RUN: cp "%s" "%t/test.cpp" -// RUN: clang-doc --doxygen --executor=standalone -p %t %t/test.cpp -output=%t/docs -// RUN: cat %t/docs/index.yaml | FileCheck %s --check-prefix=CHECK -// RUN: rm -rf %t + +// RUN: clang-doc --doxygen --executor=standalone %s -output=%t/docs +// RUN: cat %t/docs/index.yaml | FileCheck %s --check-prefix=YAML + +// RUN: clang-doc --doxygen --executor=standalone %s -output=%t/docs --format=md +// RUN: cat %t/docs/GlobalNamespace/index.md | FileCheck %s --check-prefix=MD + +// YAML: --- +// YAML-NEXT: USR: '{{([0-9A-F]{40})}}' +// YAML-NEXT: ChildRecords: +// YAML-NEXT: - Type: Record +// YAML-NEXT: Name: 'tuple' +// YAML-NEXT: QualName: 'tuple' +// YAML-NEXT: USR: '{{([0-9A-F]{40})}}' +// YAML-NEXT: Path: 'GlobalNamespace' + +// MD: # Global Namespace +// MD: ## Functions + +template +void ParamPackFunction(T... args); + +// YAML-NEXT: ChildFunctions: +// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}' +// YAML-NEXT: Name: 'ParamPackFunction' +// YAML-NEXT: Location: +// YAML-NEXT: - LineNumber: [[# @LINE - 6]] +// YAML-NEXT: Filename: '{{.*}}' +// YAML-NEXT: Params: +// YAML-NEXT: - Type: +// YAML-NEXT: Name: 'T...' +// YAML-NEXT: QualName: 'T...' +// YAML-NEXT: Name: 'args' +// YAML-NEXT: ReturnType: +// YAML-NEXT: Type: +// YAML-NEXT: Name: 'void' +// YAML-NEXT: QualName: 'void' +// YAML-NEXT: Template: +// YAML-NEXT: Params: +// YAML-NEXT: - Contents: 'class... T' + +// MD: ### ParamPackFunction +// MD: *void ParamPackFunction(T... args)* template void function(T x) {} +// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}' +// YAML-NEXT: Name: 'function' +// YAML-NEXT: DefLocation: +// YAML-NEXT: LineNumber: [[# @LINE - 5]] +// YAML-NEXT: Filename: '{{.*}}' +// YAML-NEXT: Params: +// YAML-NEXT: - Type: +// YAML-NEXT: Name: 'T' +// YAML-NEXT: QualName: 'T' +// YAML-NEXT: Name: 'x' +// YAML-NEXT: ReturnType: +// YAML-NEXT: Type: +// YAML-NEXT: Name: 'void' +// YAML-NEXT: QualName: 'void' +// YAML-NEXT: Template: +// YAML-NEXT: Params: +// YAML-NEXT: - Contents: 'typename T' +// YAML-NEXT: - Contents: 'int U = 1' + +// MD: ### function +// MD: *void function(T x)* +// MD: *Defined at {{.*}}templates.cpp#[[# @LINE - 23]]* + template<> void function(bool x) {} -template -void ParamPackFunction(T... args); +// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}' +// YAML-NEXT: Name: 'function' +// YAML-NEXT: DefLocation: +// YAML-NEXT: LineNumber: [[# @LINE - 6]] +// YAML-NEXT: Filename: '{{.*}}' +// YAML-NEXT: Params: +// YAML-NEXT: - Type: +// YAML-NEXT: Name: '_Bool' +// YAML-NEXT: QualName: '_Bool' +// YAML-NEXT: Name: 'x' +// YAML-NEXT: ReturnType: +// YAML-NEXT: Type: +// YAML-NEXT: Name: 'void' +// YAML-NEXT: QualName: 'void' +// YAML-NEXT: Template: +// YAML-NEXT: Specialization: +// YAML-NEXT: SpecializationOf: '{{([0-9A-F]{40})}}' +// YAML-NEXT: Params: +// YAML-NEXT: - Contents: 'bool' +// YAML-NEXT: - Contents: '0' + +// MD: ### function +// MD: *void function(_Bool x)* +// MD: *Defined at {{.*}}templates.cpp#[[# @LINE - 26]]* + +/// A Tuple type +/// +/// Does Tuple things. +template +struct tuple{}; + +/// A function with a tuple parameter +/// +/// \param t The input to func_with_tuple_param +tuple func_with_tuple_param(tuple t){ return t;} + +// YAML-NEXT: - USR: '{{([0-9A-F]{40})}}' +// YAML-NEXT: Name: 'func_with_tuple_param' +// YAML-NEXT: Description: +// YAML-NEXT: - Kind: 'FullComment' +// YAML-NEXT: Children: +// YAML-NEXT: - Kind: 'ParagraphComment' +// YAML-NEXT: Children: +// YAML-NEXT: - Kind: 'TextComment' +// YAML-NEXT: Text: ' A function with a tuple parameter' +// YAML-NEXT: - Kind: 'ParagraphComment' +// YAML-NEXT: Children: +// YAML-NEXT: - Kind: 'TextComment' +// YAML-NEXT: - Kind: 'ParamCommandComment' +// YAML-NEXT: Direction: '[in]' +// YAML-NEXT: ParamName: 't' +// YAML-NEXT: Children: +// YAML-NEXT: - Kind: 'ParagraphComment' +// YAML-NEXT: Children: +// YAML-NEXT: - Kind: 'TextComment' +// YAML-NEXT: Text: ' The input to func_with_tuple_param' +// YAML-NEXT: DefLocation: +// YAML-NEXT: LineNumber: [[# @LINE - 23]] +// YAML-NEXT: Filename: +// YAML-NEXT: Params: +// YAML-NEXT: - Type: +// YAML-NEXT: Type: Record +// YAML-NEXT: Name: 'tuple' +// YAML-NEXT: QualName: 'tuple' +// YAML-NEXT: USR: '{{([0-9A-F]{40})}}' +// YAML-NEXT: Path: 'GlobalNamespace' +// YAML-NEXT: Name: 't' +// YAML-NEXT: ReturnType: +// YAML-NEXT: Type: +// YAML-NEXT: Type: Record +// YAML-NEXT: Name: 'tuple' +// YAML-NEXT: QualName: 'tuple' +// YAML-NEXT: USR: '{{([0-9A-F]{40})}}' +// YAML-NEXT: Path: 'GlobalNamespace' +// YAML-NEXT: ... + +// MD: ### func_with_tuple_param +// MD: *tuple func_with_tuple_param(tuple t)* +// MD: *Defined at {{.*}}templates.cpp#[[# @LINE - 44]]* +// MD: A function with a tuple parameter +// MD: **t** The input to func_with_tuple_param -// CHECK: --- -// CHECK-NEXT: USR: '{{([0-9A-F]{40})}}' -// CHECK-NEXT: ChildFunctions: -// CHECK-NEXT: - USR: '{{([0-9A-F]{40})}}' -// CHECK-NEXT: Name: 'ParamPackFunction' -// CHECK-NEXT: Location: -// CHECK-NEXT: - LineNumber: 16 -// CHECK-NEXT: Filename: '{{.*}}' -// CHECK-NEXT: Params: -// CHECK-NEXT: - Type: -// CHECK-NEXT: Name: 'T...' -// CHECK-NEXT: QualName: 'T...' -// CHECK-NEXT: Name: 'args' -// CHECK-NEXT: ReturnType: -// CHECK-NEXT: Type: -// CHECK-NEXT: Name: 'void' -// CHECK-NEXT: QualName: 'void' -// CHECK-NEXT: Template: -// CHECK-NEXT: Params: -// CHECK-NEXT: - Contents: 'class... T' -// CHECK-NEXT: - USR: '{{([0-9A-F]{40})}}' -// CHECK-NEXT: Name: 'function' -// CHECK-NEXT: DefLocation: -// CHECK-NEXT: LineNumber: 10 -// CHECK-NEXT: Filename: '{{.*}}' -// CHECK-NEXT: Params: -// CHECK-NEXT: - Type: -// CHECK-NEXT: Name: 'T' -// CHECK-NEXT: QualName: 'T' -// CHECK-NEXT: Name: 'x' -// CHECK-NEXT: ReturnType: -// CHECK-NEXT: Type: -// CHECK-NEXT: Name: 'void' -// CHECK-NEXT: QualName: 'void' -// CHECK-NEXT: Template: -// CHECK-NEXT: Params: -// CHECK-NEXT: - Contents: 'typename T' -// CHECK-NEXT: - Contents: 'int U = 1' -// CHECK-NEXT: - USR: '{{([0-9A-F]{40})}}' -// CHECK-NEXT: Name: 'function' -// CHECK-NEXT: DefLocation: -// CHECK-NEXT: LineNumber: 12 -// CHECK-NEXT: Filename: '{{.*}}' -// CHECK-NEXT: Params: -// CHECK-NEXT: - Type: -// CHECK-NEXT: Name: '_Bool' -// CHECK-NEXT: QualName: '_Bool' -// CHECK-NEXT: Name: 'x' -// CHECK-NEXT: ReturnType: -// CHECK-NEXT: Type: -// CHECK-NEXT: Name: 'void' -// CHECK-NEXT: QualName: 'void' -// CHECK-NEXT: Template: -// CHECK-NEXT: Specialization: -// CHECK-NEXT: SpecializationOf: '{{([0-9A-F]{40})}}' -// CHECK-NEXT: Params: -// CHECK-NEXT: - Contents: 'bool' -// CHECK-NEXT: - Contents: '0' -// CHECK-NEXT: ... diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp new file mode 100644 index 0000000000000..768ab1ce014ce --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/optional-value-conversion-construct-from-std.cpp @@ -0,0 +1,53 @@ +// RUN: %check_clang_tidy -std=c++17-or-later %s bugprone-optional-value-conversion %t + +namespace std { +template struct optional { + constexpr optional() noexcept; + constexpr optional(T &&) noexcept; + constexpr optional(const T &) noexcept; + template constexpr optional(U &&) noexcept; + const T &operator*() const; + T *operator->(); + const T *operator->() const; + T &operator*(); + const T &value() const; + T &value(); + const T &get() const; + T &get(); + T value_or(T) const; +}; + +template T &&move(T &x) { return static_cast(x); } + +template class default_delete {}; + +template > +class unique_ptr {}; + +template +class shared_ptr {}; + +template unique_ptr make_unique(Args &&...args); +template shared_ptr make_shared(Args &&...args); + +} // namespace std + +struct A { + explicit A (int); +}; +std::optional opt; + +void invalid() { + std::make_unique>(opt.value()); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional' into 'int' and back into 'std::optional', remove potentially error-prone optional dereference [bugprone-optional-value-conversion] + using A = std::optional; + std::make_unique(opt.value()); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional' into 'int' and back into 'std::optional', remove potentially error-prone optional dereference [bugprone-optional-value-conversion] + std::make_shared>(opt.value()); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: conversion from 'std::optional' into 'int' and back into 'std::optional', remove potentially error-prone optional dereference [bugprone-optional-value-conversion] +} + +void valid() { + std::make_unique(opt.value()); + std::make_shared(opt.value()); +} diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp index 46cb9063beda9..a3297ca0f8084 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/return-const-ref-from-parameter.cpp @@ -203,3 +203,26 @@ namespace use_lifetime_bound_attr { int const &f(int const &a [[clang::lifetimebound]]) { return a; } } // namespace use_lifetime_bound_attr } // namespace gh117696 + + +namespace lambda { +using T = const int &; +using K = const float &; +T inner_valid_lambda(T a) { + [&]() -> T { return a; }; + return a; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: returning a constant reference parameter +} +T inner_invalid_lambda(T a) { + [&](T a) -> T { return a; }; + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: returning a constant reference parameter + return a; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: returning a constant reference parameter +} +T inner_invalid_lambda2(T a) { + [&](K a) -> K { return a; }; + // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: returning a constant reference parameter + return a; + // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: returning a constant reference parameter +} +} // namespace lambda diff --git a/clang-tools-extra/test/clang-tidy/checkers/fuchsia/default-arguments-calls.cpp b/clang-tools-extra/test/clang-tidy/checkers/fuchsia/default-arguments-calls.cpp index ed9079092f6ac..50b6d4c5676c3 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/fuchsia/default-arguments-calls.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/fuchsia/default-arguments-calls.cpp @@ -26,7 +26,7 @@ void S::x(int i = 12) {} int main() { S s; s.x(); - // CHECK-NOTES: [[@LINE-1]]:3: warning: calling a function that uses a default argument is disallowed [fuchsia-default-arguments-calls] + // CHECK-NOTES: [[@LINE-1]]:5: warning: calling a function that uses a default argument is disallowed [fuchsia-default-arguments-calls] // CHECK-NOTES: [[@LINE-6]]:11: note: default parameter was declared here // CHECK-NEXT: void S::x(int i = 12) {} x(); diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp index 1b271630e0d19..7396d2dce76c4 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc/redundant-expression.cpp @@ -1,4 +1,4 @@ -// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing +// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing -Wno-array-compare-cxx26 typedef __INT64_TYPE__ I64; diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp new file mode 100644 index 0000000000000..99f00444c2d3f --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-integer-sign-comparison.cpp @@ -0,0 +1,122 @@ +// CHECK-FIXES: #include +// RUN: %check_clang_tidy -std=c++20 %s modernize-use-integer-sign-comparison %t + +// The code that triggers the check +#define MAX_MACRO(a, b) (a < b) ? b : a + +unsigned int FuncParameters(int bla) { + unsigned int result = 0; + if (result == bla) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_equal(result , bla)) + + return 1; +} + +template +void TemplateFuncParameter(T val) { + unsigned long uL = 0; + if (val >= uL) + return; +// CHECK-MESSAGES-NOT: warning: +} + +template +int TemplateFuncParameters(T1 val1, T2 val2) { + if (val1 >= val2) + return 0; +// CHECK-MESSAGES-NOT: warning: + return 1; +} + +int AllComparisons() { + unsigned int uVar = 42; + unsigned short uArray[7] = {0, 1, 2, 3, 9, 7, 9}; + + int sVar = -42; + short sArray[7] = {-1, -2, -8, -94, -5, -4, -6}; + + enum INT_TEST { + VAL1 = 0, + VAL2 = -1 + }; + + char ch = 'a'; + unsigned char uCh = 'a'; + signed char sCh = 'a'; + bool bln = false; + + if (bln == sVar) + return 0; +// CHECK-MESSAGES-NOT: warning: + + if (ch > uCh) + return 0; +// CHECK-MESSAGES-NOT: warning: + + if (sVar <= INT_TEST::VAL2) + return 0; +// CHECK-MESSAGES-NOT: warning: + + if (uCh < sCh) + return -1; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_less(uCh , sCh)) + + if ((int)uVar < sVar) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_less(uVar, sVar)) + + (uVar != sVar) ? uVar = sVar + : sVar = uVar; +// CHECK-MESSAGES: :[[@LINE-2]]:6: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: (std::cmp_not_equal(uVar , sVar)) ? uVar = sVar + + while (uArray[0] <= sArray[0]) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:12: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: while (std::cmp_less_equal(uArray[0] , sArray[0])) + + if (uArray[1] > sArray[1]) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_greater(uArray[1] , sArray[1])) + + MAX_MACRO(uVar, sArray[0]); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] + + if (static_cast(uArray[2]) < static_cast(sArray[2])) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_less(uArray[2],sArray[2])) + + if ((unsigned int)uArray[3] < (int)sArray[3]) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_less(uArray[3],sArray[3])) + + if ((unsigned int)(uArray[4]) < (int)(sArray[4])) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_less((uArray[4]),(sArray[4]))) + + if (uArray[5] > sArray[5]) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_greater(uArray[5] , sArray[5])) + + #define VALUE sArray[6] + if (uArray[6] > VALUE) + return 0; +// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: comparison between 'signed' and 'unsigned' integers [modernize-use-integer-sign-comparison] +// CHECK-FIXES: if (std::cmp_greater(uArray[6] , VALUE)) + + + FuncParameters(uVar); + TemplateFuncParameter(sVar); + TemplateFuncParameters(uVar, sVar); + + return 0; +} diff --git a/clang/Maintainers.rst b/clang/Maintainers.rst index 7396211715a80..f9732aade7186 100644 --- a/clang/Maintainers.rst +++ b/clang/Maintainers.rst @@ -320,8 +320,8 @@ OpenMP conformance OpenCL conformance ~~~~~~~~~~~~~~~~~~ -| Anastasia Stulova -| anastasia\@compiler-experts.com (email), Anastasia (Phabricator), AnastasiaStulova (GitHub) +| Sven van Haastregt +| sven.vanhaastregt\@arm.com (email), svenvh (GitHub) OpenACC @@ -365,6 +365,7 @@ Emeritus Lead Maintainers Inactive component maintainers ------------------------------ +| Anastasia Stulova (stulovaa\@gmail.com) -- OpenCL, C++ for OpenCL | Chandler Carruth (chandlerc\@gmail.com, chandlerc\@google.com) -- CMake, library layering | Devin Coughlin (dcoughlin\@apple.com) -- Clang static analyzer | Manuel Klimek (klimek\@google.com (email), klimek (Phabricator), r4nt (GitHub)) -- Tooling, AST matchers diff --git a/clang/cmake/caches/Fuchsia-stage2.cmake b/clang/cmake/caches/Fuchsia-stage2.cmake index 784a883a3bf91..8e161f868d4af 100644 --- a/clang/cmake/caches/Fuchsia-stage2.cmake +++ b/clang/cmake/caches/Fuchsia-stage2.cmake @@ -300,19 +300,22 @@ if(FUCHSIA_SDK) set(LLVM_RUNTIME_MULTILIB_hwasan+noexcept_TARGETS "aarch64-unknown-fuchsia;riscv64-unknown-fuchsia" CACHE STRING "") endif() -foreach(target armv6m-none-eabi;armv7m-none-eabi;armv8m.main-none-eabi;armv8.1m.main-none-eabi) +foreach(target armv6m-none-eabi;armv7m-none-eabi;armv8m.main-none-eabi;armv8.1m.main-none-eabi;aarch64-none-elf) list(APPEND BUILTIN_TARGETS "${target}") set(BUILTINS_${target}_CMAKE_SYSTEM_NAME Generic CACHE STRING "") set(BUILTINS_${target}_CMAKE_SYSTEM_PROCESSOR arm CACHE STRING "") set(BUILTINS_${target}_CMAKE_SYSROOT "" CACHE STRING "") set(BUILTINS_${target}_CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "") foreach(lang C;CXX;ASM) - set(BUILTINS_${target}_CMAKE_${lang}_local_flags "--target=${target} -mthumb") + set(BUILTINS_${target}_CMAKE_${lang}_local_flags "--target=${target}") + if(NOT ${target} STREQUAL "aarch64-none-elf") + set(BUILTINS_${target}_CMAKE_${lang}_local_flags "${BUILTINS_${target}_CMAKE_${lang}_local_flags} -mthumb") + endif() if(${target} STREQUAL "armv8m.main-none-eabi") - set(BUILTINS_${target}_CMAKE_${lang}_local_flags "${BUILTINS_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=softfp -march=armv8m.main+fp+dsp -mcpu=cortex-m33" CACHE STRING "") + set(BUILTINS_${target}_CMAKE_${lang}_local_flags "${BUILTINS_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=softfp -march=armv8m.main+fp+dsp -mcpu=cortex-m33") endif() if(${target} STREQUAL "armv8.1m.main-none-eabi") - set(BUILTINS_${target}_CMAKE_${lang}_local_flags "${BUILTINS_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=hard -march=armv8.1-m.main+mve.fp+fp.dp -mcpu=cortex-m55" CACHE STRING "") + set(BUILTINS_${target}_CMAKE_${lang}_local_flags "${BUILTINS_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=hard -march=armv8.1-m.main+mve.fp+fp.dp -mcpu=cortex-m55") endif() set(BUILTINS_${target}_CMAKE_${lang}_FLAGS "${BUILTINS_${target}_CMAKE_${lang}_local_flags}" CACHE STRING "") endforeach() @@ -330,12 +333,15 @@ foreach(target armv6m-none-eabi;armv7m-none-eabi;armv8m.main-none-eabi;armv8.1m. foreach(lang C;CXX;ASM) # TODO: The preprocessor defines workaround various issues in libc and libc++ integration. # These should be addressed and removed over time. - set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "--target=${target} -mthumb -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dgettimeofday(tv, tz)\" -D_LIBCPP_PRINT=1") + set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "--target=${target} -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dgettimeofday(tv, tz)\" -D_LIBCPP_PRINT=1") + if(NOT ${target} STREQUAL "aarch64-none-elf") + set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "${RUNTIMES_${target}_CMAKE_${lang}_local_flags} -mthumb") + endif() if(${target} STREQUAL "armv8m.main-none-eabi") - set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "${RUNTIMES_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=softfp -march=armv8m.main+fp+dsp -mcpu=cortex-m33" CACHE STRING "") + set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "${RUNTIMES_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=softfp -march=armv8m.main+fp+dsp -mcpu=cortex-m33") endif() if(${target} STREQUAL "armv8.1m.main-none-eabi") - set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "${RUNTIMES_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=hard -march=armv8.1-m.main+mve.fp+fp.dp -mcpu=cortex-m55" CACHE STRING "") + set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "${RUNTIMES_${target}_CMAKE_${lang}_local_flags} -mfloat-abi=hard -march=armv8.1-m.main+mve.fp+fp.dp -mcpu=cortex-m55") endif() set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "${RUNTIMES_${target}_CMAKE_${lang}_local_flags}" CACHE STRING "") endforeach() diff --git a/clang/docs/LanguageExtensions.rst b/clang/docs/LanguageExtensions.rst index 6b950d05fb9bf..3d4f68b818bce 100644 --- a/clang/docs/LanguageExtensions.rst +++ b/clang/docs/LanguageExtensions.rst @@ -648,7 +648,8 @@ elementwise to the input. Unless specified otherwise operation(±0) = ±0 and operation(±infinity) = ±infinity The integer elementwise intrinsics, including ``__builtin_elementwise_popcount``, -``__builtin_elementwise_bitreverse``, can be called in a ``constexpr`` context. +``__builtin_elementwise_bitreverse``, ``__builtin_elementwise_add_sat``, +``__builtin_elementwise_sub_sat`` can be called in a ``constexpr`` context. ============================================== ====================================================================== ========================================= Name Operation Supported element types @@ -4525,9 +4526,13 @@ default member initializer, the invocation point is the location of the constructor or aggregate initialization used to create the object. Otherwise the invocation point is the same as the location of the builtin. -When the invocation point of ``__builtin_FUNCTION`` is not a function scope the +When the invocation point of ``__builtin_FUNCTION`` is not a function scope, the empty string is returned. +The builtin ``__builtin_COLUMN`` returns the offset from the start of the line, +beginning from column 1. `This may differ from other implementations. +`_ + The builtin ``__builtin_source_location`` returns a pointer to constant static data of type ``std::source_location::__impl``. This type must have already been defined, and must contain exactly four fields: ``const char *_M_file_name``, @@ -5550,7 +5555,7 @@ The ``#pragma clang section`` directive obeys the following rules: * Global variables that are initialized to zero will be placed in the named bss section, if one is present. -* The ``#pragma clang section`` directive does not does try to infer section-kind +* The ``#pragma clang section`` directive does not try to infer section-kind from the name. For example, naming a section "``.bss.mySec``" does NOT mean it will be a bss section name. diff --git a/clang/docs/MatrixTypes.rst b/clang/docs/MatrixTypes.rst index e32e13b73aba6..32949c6c43529 100644 --- a/clang/docs/MatrixTypes.rst +++ b/clang/docs/MatrixTypes.rst @@ -33,9 +33,10 @@ program is ill-formed. Currently, the element type of a matrix is only permitted to be one of the following types: -* an integer type (as in C23 6.2.5p22), but excluding enumerated types and ``bool`` -* the standard floating types ``float`` or ``double`` -* a half-precision floating point type, if one is supported on the target +* an integer type (as in C23 6.2.5p22), but excluding enumerated types, ``bool``, + and ``_BitInt`` types whose width is not a power of 2; +* the standard floating types ``float`` or ``double``; +* a half-precision floating point type, if one is supported on the target. Other types may be supported in the future. diff --git a/clang/docs/RealtimeSanitizer.rst b/clang/docs/RealtimeSanitizer.rst index 233a91f668416..f5d29af2bef3c 100644 --- a/clang/docs/RealtimeSanitizer.rst +++ b/clang/docs/RealtimeSanitizer.rst @@ -187,16 +187,19 @@ A **partial** list of flags RealtimeSanitizer respects: * - ``abort_on_error`` - OS dependent - boolean - - If true, the tool calls abort() instead of _exit() after printing the error report. On some OSes (OSX, for exmple) this is beneficial because a better stack trace is emitted on crash. + - If true, the tool calls ``abort()`` instead of ``_exit()`` after printing the error report. On some OSes (MacOS, for exmple) this is beneficial because a better stack trace is emitted on crash. * - ``symbolize`` - ``true`` - boolean - If set, use the symbolizer to turn virtual addresses to file/line locations. If false, can greatly speed up the error reporting. * - ``suppressions`` - - "" + - ``""`` - path - - If set to a valid suppressions file, will suppress issue reporting. See details in "Disabling", below. - + - If set to a valid suppressions file, will suppress issue reporting. See details in `Disabling and Suppressing`_. + * - ``verify_interceptors`` + - ``true`` + - boolean + - If true, verifies interceptors are working at initialization. The program will abort with error ``==ERROR: Interceptors are not working. This may be because RealtimeSanitizer is loaded too late (e.g. via dlopen)`` if an issue is detected. Some issues with flags can be debugged using the ``verbosity=$NUM`` flag: @@ -244,6 +247,7 @@ To register a callback which will be invoked before a RTSan kills the process: ... } +.. _disabling-and-suppressing: Disabling and suppressing ------------------------- diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index e484eb7a76e63..38aab8c7d32ca 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -61,6 +61,8 @@ code bases. C/C++ Language Potentially Breaking Changes ------------------------------------------- +- Clang now rejects ``_Complex _BitInt`` types. + C++ Specific Potentially Breaking Changes ----------------------------------------- @@ -408,12 +410,14 @@ Non-comprehensive list of changes in this release The flexible array member (FAM) can now be accessed immediately without causing issues with the sanitizer because the counter is automatically set. -- ``__builtin_reduce_add`` function can now be used in constant expressions. -- ``__builtin_reduce_mul`` function can now be used in constant expressions. -- ``__builtin_reduce_and`` function can now be used in constant expressions. -- ``__builtin_reduce_or`` and ``__builtin_reduce_xor`` functions can now be used in constant expressions. -- ``__builtin_elementwise_popcount`` function can now be used in constant expressions. -- ``__builtin_elementwise_bitreverse`` function can now be used in constant expressions. +- The following builtins can now be used in constant expressions: ``__builtin_reduce_add``, + ``__builtin_reduce_mul``, ``__builtin_reduce_and``, ``__builtin_reduce_or``, + ``__builtin_reduce_xor``, ``__builtin_elementwise_popcount``, + ``__builtin_elementwise_bitreverse``, ``__builtin_elementwise_add_sat``, + ``__builtin_elementwise_sub_sat``. + +- Clang now rejects ``_BitInt`` matrix element types if the bit width is less than ``CHAR_WIDTH`` or + not a power of two, matching preexisting behaviour for vector types. New Compiler Flags ------------------ @@ -428,6 +432,9 @@ New Compiler Flags - The ``-Warray-compare`` warning has been added to warn about array comparison on versions older than C++20. +- The ``-Warray-compare-cxx26`` warning has been added to warn about array comparison + starting from C++26, this warning is enabled as an error by default. + Deprecated Compiler Flags ------------------------- @@ -456,6 +463,10 @@ Modified Compiler Flags ``memset`` and similar functions for which it is a documented undefined behavior. It is implied by ``-Wnontrivial-memaccess`` +- Added ``-fmodules-reduced-bmi`` flag corresponding to + ``-fexperimental-modules-reduced-bmi`` flag. The ``-fmodules-reduced-bmi`` flag + is intended to be enabled by default in the future. + Removed Compiler Flags ------------------------- @@ -525,6 +536,9 @@ Attribute Changes in Clang - The ``target_version`` attribute is now only supported for AArch64 and RISC-V architectures. +- Clang now permits the usage of the placement new operator in ``[[msvc::constexpr]]`` + context outside of the std namespace. (#GH74924) + Improvements to Clang's diagnostics ----------------------------------- @@ -603,6 +617,8 @@ Improvements to Clang's diagnostics - Clang now diagnoses ``[[deprecated]]`` attribute usage on local variables (#GH90073). +- Fix false positives when `[[gsl::Owner/Pointer]]` and `[[clang::lifetimebound]]` are used together. + - Improved diagnostic message for ``__builtin_bit_cast`` size mismatch (#GH115870). - Clang now omits shadow warnings for enum constants in separate class scopes (#GH62588). @@ -641,6 +657,29 @@ Improvements to Clang's diagnostics - Clang now diagnoses dangling references for C++20's parenthesized aggregate initialization (#101957). +- Fixed a bug where Clang would not emit ``-Wunused-private-field`` warnings when an unrelated class + defined a defaulted comparison operator (#GH116270). + + .. code-block:: c++ + + class A { + private: + int a; // warning: private field 'a' is not used, no diagnostic previously + }; + + class C { + bool operator==(const C&) = default; + }; + +- Clang now emits `-Wdangling-capture` diangostic when a STL container captures a dangling reference. + + .. code-block:: c++ + + void test() { + std::vector views; + views.push_back(std::string("123")); // warning + } + Improvements to Clang's time-trace ---------------------------------- @@ -663,6 +702,9 @@ Bug Fixes in This Version - Fixed a crash when GNU statement expression contains invalid statement (#GH113468). - Fixed a failed assertion when using ``__attribute__((noderef))`` on an ``_Atomic``-qualified type (#GH116124). +- No longer return ``false`` for ``noexcept`` expressions involving a + ``delete`` which resolves to a destroying delete but the type of the object + being deleted has a potentially throwing destructor (#GH118660). Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -676,6 +718,8 @@ Bug Fixes to Compiler Builtins - Fix ``__has_builtin`` incorrectly returning ``false`` for some C++ type traits. (#GH111477) +- Fix ``__builtin_source_location`` incorrectly returning wrong column for method chains. (#GH119129) + Bug Fixes to Attribute Support ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -776,10 +820,14 @@ Bug Fixes to C++ Support - Fixed a bug where bounds of partially expanded pack indexing expressions were checked too early. (#GH116105) - Fixed an assertion failure caused by using ``consteval`` in condition in consumed analyses. (#GH117385) - Fix a crash caused by incorrect argument position in merging deduced template arguments. (#GH113659) +- Fixed a parser crash when using pack indexing as a nested name specifier. (#GH119072) +- Fixed a null pointer dereference issue when heuristically computing ``sizeof...(pack)`` expressions. (#GH81436) - Fixed an assertion failure caused by mangled names with invalid identifiers. (#GH112205) - Fixed an incorrect lambda scope of generic lambdas that caused Clang to crash when computing potential lambda captures at the end of a full expression. (#GH115931) - Clang no longer rejects deleting a pointer of incomplete enumeration type. (#GH99278) +- Fixed recognition of ``std::initializer_list`` when it's surrounded with ``extern "C++"`` and exported + out of a module (which is the case e.g. in MSVC's implementation of ``std`` module). (#GH118218) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/docs/StandardCPlusPlusModules.rst b/clang/docs/StandardCPlusPlusModules.rst index 8e22adad15106..93edce0cf90b7 100644 --- a/clang/docs/StandardCPlusPlusModules.rst +++ b/clang/docs/StandardCPlusPlusModules.rst @@ -602,16 +602,16 @@ unnecessary dependencies for the BMI. To mitigate the problem, Clang has a compiler option to reduce the information contained in the BMI. These two formats are known as Full BMI and Reduced BMI, respectively. -Users can use the ``-fexperimental-modules-reduced-bmi`` option to produce a +Users can use the ``-fmodules-reduced-bmi`` option to produce a Reduced BMI. For the one-phase compilation model (CMake implements this model), with -``-fexperimental-modules-reduced-bmi``, the generated BMI will be a Reduced +``-fmodules-reduced-bmi``, the generated BMI will be a Reduced BMI automatically. (The output path of the BMI is specified by ``-fmodule-output=`` as usual with the one-phase compilation model). It is also possible to produce a Reduced BMI with the two-phase compilation -model. When ``-fexperimental-modules-reduced-bmi``, ``--precompile``, and +model. When ``-fmodules-reduced-bmi``, ``--precompile``, and ``-fmodule-output=`` are specified, the generated BMI specified by ``-o`` will be a full BMI and the BMI specified by ``-fmodule-output=`` will be a Reduced BMI. The dependency graph in this case would look like: @@ -625,7 +625,7 @@ BMI. The dependency graph in this case would look like: -> ... -> consumer_n.cpp -Clang does not emit diagnostics when ``-fexperimental-modules-reduced-bmi`` is +Clang does not emit diagnostics when ``-fmodules-reduced-bmi`` is used with a non-module unit. This design permits users of the one-phase compilation model to try using reduced BMIs without needing to modify the build system. The two-phase compilation module requires build system support. @@ -691,11 +691,10 @@ ensure it is reachable, e.g. ``using N::g;``. Support for Reduced BMIs is still experimental, but it may become the default in the future. The expected roadmap for Reduced BMIs as of Clang 19.x is: -1. ``-fexperimental-modules-reduced-bmi`` is opt-in for 1~2 releases. The period depends +1. ``-fexperimental-modules-reduced-bmi`` was introduced in v19.x +2. For v20.x, ``-fmodules-reduced-bmi`` is introduced as an equivalent non-experimental + option. It is expected to stay opt-in for 1~2 releases, though the period depends on user feedback and may be extended. -2. Announce that Reduced BMIs are no longer experimental and introduce - ``-fmodules-reduced-bmi`` as a new option, and recommend use of the new - option. This transition is expected to take 1~2 additional releases as well. 3. Finally, ``-fmodules-reduced-bmi`` will be the default. When that time comes, the term BMI will refer to the Reduced BMI and the Full BMI will only be meaningful to build systems which elect to support two-phase compilation. @@ -814,8 +813,8 @@ With reduced BMI, non-cascading changes can be more powerful. For example, .. code-block:: console - $ clang++ -std=c++20 A.cppm -c -fmodule-output=A.pcm -fexperimental-modules-reduced-bmi -o A.o - $ clang++ -std=c++20 B.cppm -c -fmodule-output=B.pcm -fexperimental-modules-reduced-bmi -o B.o -fmodule-file=A=A.pcm + $ clang++ -std=c++20 A.cppm -c -fmodule-output=A.pcm -fmodules-reduced-bmi -o A.o + $ clang++ -std=c++20 B.cppm -c -fmodule-output=B.pcm -fmodules-reduced-bmi -o B.o -fmodule-file=A=A.pcm $ md5sum B.pcm 6c2bd452ca32ab418bf35cd141b060b9 B.pcm @@ -831,8 +830,8 @@ and recompile the example: .. code-block:: console - $ clang++ -std=c++20 A.cppm -c -fmodule-output=A.pcm -fexperimental-modules-reduced-bmi -o A.o - $ clang++ -std=c++20 B.cppm -c -fmodule-output=B.pcm -fexperimental-modules-reduced-bmi -o B.o -fmodule-file=A=A.pcm + $ clang++ -std=c++20 A.cppm -c -fmodule-output=A.pcm -fmodules-reduced-bmi -o A.o + $ clang++ -std=c++20 B.cppm -c -fmodule-output=B.pcm -fmodules-reduced-bmi -o B.o -fmodule-file=A=A.pcm $ md5sum B.pcm 6c2bd452ca32ab418bf35cd141b060b9 B.pcm diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 43b41a2a82689..8af9f5be644a0 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -1059,6 +1059,17 @@ In this way, the user may only need to specify a root configuration file with -L /lib -T /ldscripts/link.ld +Usually, config file options are placed before command-line options, regardless +of the actual operation to be performed. The exception is being made for the +options prefixed with the ``$`` character. These will be used only when linker +is being invoked, and added after all of the command-line specified linker +inputs. Here is some example of ``$``-prefixed options: + +:: + + $-Wl,-Bstatic $-lm + $-Wl,-Bshared + Language and Target-Independent Features ======================================== diff --git a/clang/docs/analyzer/checkers.rst b/clang/docs/analyzer/checkers.rst index d99d4035a57ac..29d5e1f92a69c 100644 --- a/clang/docs/analyzer/checkers.rst +++ b/clang/docs/analyzer/checkers.rst @@ -3438,6 +3438,31 @@ alpha.WebKit .. _alpha-webkit-NoUncheckedPtrMemberChecker: +alpha.webkit.MemoryUnsafeCastChecker +"""""""""""""""""""""""""""""""""""""" +Check for all casts from a base type to its derived type as these might be memory-unsafe. + +Example: + +.. code-block:: cpp + + class Base { }; + class Derived : public Base { }; + + void f(Base* base) { + Derived* derived = static_cast(base); // ERROR + } + +For all cast operations (C-style casts, static_cast, reinterpret_cast, dynamic_cast), if the source type a `Base*` and the destination type is `Derived*`, where `Derived` inherits from `Base`, the static analyzer should signal an error. + +This applies to: + +- C structs, C++ structs and classes, and Objective-C classes and protocols. +- Pointers and references. +- Inside template instantiations and macro expansions that are visible to the compiler. + +For types like this, instead of using built in casts, the programmer will use helper functions that internally perform the appropriate type check and disable static analysis. + alpha.webkit.NoUncheckedPtrMemberChecker """""""""""""""""""""""""""""""""""""""" Raw pointers and references to an object which supports CheckedPtr or CheckedRef can't be used as class members. Only CheckedPtr, CheckedRef, RefPtr, or Ref are allowed. diff --git a/clang/docs/tools/dump_format_help.py b/clang/docs/tools/dump_format_help.py index 1a9afde1b9db9..ba41ed8c02c81 100755 --- a/clang/docs/tools/dump_format_help.py +++ b/clang/docs/tools/dump_format_help.py @@ -2,6 +2,7 @@ # A tool to parse the output of `clang-format --help` and update the # documentation in ../ClangFormat.rst automatically. +import argparse import os import re import subprocess @@ -26,7 +27,7 @@ def indent(text, columns, indent_first_line=True): def get_help_output(): - args = ["clang-format", "--help"] + args = [binary, "--help"] cmd = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out, _ = cmd.communicate() out = out.decode(sys.stdout.encoding) @@ -54,13 +55,24 @@ def validate(text, columns): print("warning: line too long:\n", line, file=sys.stderr) +p = argparse.ArgumentParser() +p.add_argument("-d", "--directory", help="directory of clang-format") +p.add_argument("-o", "--output", help="path of output file") +opts = p.parse_args() + +binary = "clang-format" +if opts.directory: + binary = opts.directory + "/" + binary + help_text = get_help_text() validate(help_text, 100) -with open(DOC_FILE) as f: +with open(DOC_FILE, encoding="utf-8") as f: contents = f.read() contents = substitute(contents, "FORMAT_HELP", help_text) -with open(DOC_FILE, "wb") as output: - output.write(contents.encode()) +with open( + opts.output if opts.output else DOC_FILE, "w", newline="", encoding="utf-8" +) as f: + f.write(contents) diff --git a/clang/docs/tools/dump_format_style.py b/clang/docs/tools/dump_format_style.py index c82b4479f299d..f035143f6b3d1 100755 --- a/clang/docs/tools/dump_format_style.py +++ b/clang/docs/tools/dump_format_style.py @@ -3,6 +3,7 @@ # documentation in ../ClangFormatStyleOptions.rst automatically. # Run from the directory in which this file is located to update the docs. +import argparse import inspect import os import re @@ -20,7 +21,7 @@ PLURALS_FILE = os.path.join(os.path.dirname(__file__), "plurals.txt") plurals: Set[str] = set() -with open(PLURALS_FILE, "a+") as f: +with open(PLURALS_FILE) as f: f.seek(0) plurals = set(f.read().splitlines()) @@ -410,8 +411,8 @@ class State: state = State.InStruct enums[enum.name] = enum else: - # Enum member without documentation. Must be documented where the enum - # is used. + # Enum member without documentation. Must be documented + # where the enum is used. pass elif state == State.InNestedEnum: if line.startswith("///"): @@ -474,6 +475,10 @@ class State: return options +p = argparse.ArgumentParser() +p.add_argument("-o", "--output", help="path of output file") +args = p.parse_args() + with open(FORMAT_STYLE_FILE) as f: opts = OptionsReader(f).read_options() with open(INCLUDE_STYLE_FILE) as f: @@ -487,6 +492,7 @@ class State: contents = substitute(contents, "FORMAT_STYLE_OPTIONS", options_text) -output_file_path = sys.argv[1] if len(sys.argv) == 2 else DOC_FILE -with open(output_file_path, "wb") as output: - output.write(contents.encode()) +with open( + args.output if args.output else DOC_FILE, "w", newline="", encoding="utf-8" +) as f: + f.write(contents) diff --git a/clang/include/clang-c/CXString.h b/clang/include/clang-c/CXString.h index f117010c71a46..63dce4d140ce2 100644 --- a/clang/include/clang-c/CXString.h +++ b/clang/include/clang-c/CXString.h @@ -46,6 +46,10 @@ typedef struct { /** * Retrieve the character data associated with the given string. + * + * The returned data is a reference and not owned by the user. This data + * is only valid while the `CXString` is valid. This function is similar + * to `std::string::c_str()`. */ CINDEX_LINKAGE const char *clang_getCString(CXString string); diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 8fc06328f0bce..29858f00fad74 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2166,9 +2166,27 @@ enum CXCursorKind { */ CXCursor_OpenACCLoopConstruct = 321, + /** OpenACC Combined Constructs. + */ CXCursor_OpenACCCombinedConstruct = 322, - CXCursor_LastStmt = CXCursor_OpenACCCombinedConstruct, + /** OpenACC data Construct. + */ + CXCursor_OpenACCDataConstruct = 323, + + /** OpenACC enter data Construct. + */ + CXCursor_OpenACCEnterDataConstruct = 324, + + /** OpenACC exit data Construct. + */ + CXCursor_OpenACCExitDataConstruct = 325, + + /** OpenACC host_data Construct. + */ + CXCursor_OpenACCHostDataConstruct = 326, + + CXCursor_LastStmt = CXCursor_OpenACCHostDataConstruct, /** * Cursor that represents the translation unit itself. diff --git a/clang/include/clang/APINotes/Types.h b/clang/include/clang/APINotes/Types.h index ff374ad3ada06..9c01978fd49ef 100644 --- a/clang/include/clang/APINotes/Types.h +++ b/clang/include/clang/APINotes/Types.h @@ -542,6 +542,9 @@ class FunctionInfo : public CommonEntityInfo { /// The result type of this function, as a C type. std::string ResultType; + /// Ownership convention for return value + std::string SwiftReturnOwnership; + /// The function parameters. std::vector Params; @@ -622,7 +625,8 @@ inline bool operator==(const FunctionInfo &LHS, const FunctionInfo &RHS) { LHS.NumAdjustedNullable == RHS.NumAdjustedNullable && LHS.NullabilityPayload == RHS.NullabilityPayload && LHS.ResultType == RHS.ResultType && LHS.Params == RHS.Params && - LHS.RawRetainCountConvention == RHS.RawRetainCountConvention; + LHS.RawRetainCountConvention == RHS.RawRetainCountConvention && + LHS.SwiftReturnOwnership == RHS.SwiftReturnOwnership; } inline bool operator!=(const FunctionInfo &LHS, const FunctionInfo &RHS) { diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index 7869ee386689d..4401f3a8ff482 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -157,11 +157,9 @@ class APValue { void Profile(llvm::FoldingSetNodeID &ID) const; - template - bool is() const { return Ptr.is(); } + template bool is() const { return isa(Ptr); } - template - T get() const { return Ptr.get(); } + template T get() const { return cast(Ptr); } template T dyn_cast() const { return Ptr.dyn_cast(); } diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 89fcb6789d880..1e89a6805ce9c 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -245,7 +245,11 @@ class ASTContext : public RefCountedBase { mutable llvm::FoldingSet ObjCObjectPointerTypes; mutable llvm::FoldingSet DependentUnaryTransformTypes; - mutable llvm::ContextualFoldingSet AutoTypes; + // An AutoType can have a dependency on another AutoType via its template + // arguments. Since both dependent and dependency are on the same set, + // we can end up in an infinite recursion when looking for a node if we used + // a `FoldingSet`, since both could end up in the same bucket. + mutable llvm::DenseMap AutoTypes; mutable llvm::FoldingSet DeducedTemplateSpecializationTypes; mutable llvm::FoldingSet AtomicTypes; diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index 725498e132fc2..3365ebe4d9012 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -24,6 +24,7 @@ #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/Sanitizers.h" #include "clang/Basic/SourceLocation.h" +#include "clang/Support/Compiler.h" #include "llvm/Frontend/HLSL/HLSLResource.h" #include "llvm/Support/CodeGen.h" #include "llvm/Support/ErrorHandling.h" diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 8c39ef3d5a9fa..67ee0bb412692 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -747,9 +747,9 @@ class DeclaratorDecl : public ValueDecl { /// ignoring outer template declarations. SourceLocation InnerLocStart; - bool hasExtInfo() const { return DeclInfo.is(); } - ExtInfo *getExtInfo() { return DeclInfo.get(); } - const ExtInfo *getExtInfo() const { return DeclInfo.get(); } + bool hasExtInfo() const { return isa(DeclInfo); } + ExtInfo *getExtInfo() { return cast(DeclInfo); } + const ExtInfo *getExtInfo() const { return cast(DeclInfo); } protected: DeclaratorDecl(Kind DK, DeclContext *DC, SourceLocation L, @@ -762,9 +762,8 @@ class DeclaratorDecl : public ValueDecl { friend class ASTDeclWriter; TypeSourceInfo *getTypeSourceInfo() const { - return hasExtInfo() - ? getExtInfo()->TInfo - : DeclInfo.get(); + return hasExtInfo() ? getExtInfo()->TInfo + : cast(DeclInfo); } void setTypeSourceInfo(TypeSourceInfo *TI) { @@ -3458,18 +3457,17 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable { using redeclarable_base::isFirstDecl; bool isModed() const { - return MaybeModedTInfo.getPointer().is(); + return isa(MaybeModedTInfo.getPointer()); } TypeSourceInfo *getTypeSourceInfo() const { - return isModed() ? MaybeModedTInfo.getPointer().get()->first - : MaybeModedTInfo.getPointer().get(); + return isModed() ? cast(MaybeModedTInfo.getPointer())->first + : cast(MaybeModedTInfo.getPointer()); } QualType getUnderlyingType() const { - return isModed() ? MaybeModedTInfo.getPointer().get()->second - : MaybeModedTInfo.getPointer() - .get() + return isModed() ? cast(MaybeModedTInfo.getPointer())->second + : cast(MaybeModedTInfo.getPointer()) ->getType(); } @@ -3587,10 +3585,10 @@ class TagDecl : public TypeDecl, /// otherwise, it is a null (TypedefNameDecl) pointer. llvm::PointerUnion TypedefNameDeclOrQualifier; - bool hasExtInfo() const { return TypedefNameDeclOrQualifier.is(); } - ExtInfo *getExtInfo() { return TypedefNameDeclOrQualifier.get(); } + bool hasExtInfo() const { return isa(TypedefNameDeclOrQualifier); } + ExtInfo *getExtInfo() { return cast(TypedefNameDeclOrQualifier); } const ExtInfo *getExtInfo() const { - return TypedefNameDeclOrQualifier.get(); + return cast(TypedefNameDeclOrQualifier); } protected: @@ -3793,7 +3791,7 @@ class TagDecl : public TypeDecl, TypedefNameDecl *getTypedefNameForAnonDecl() const { return hasExtInfo() ? nullptr - : TypedefNameDeclOrQualifier.get(); + : cast(TypedefNameDeclOrQualifier); } void setTypedefNameForAnonDecl(TypedefNameDecl *TDD); @@ -4011,7 +4009,7 @@ class EnumDecl : public TagDecl { return QualType(); if (const Type *T = IntegerType.dyn_cast()) return QualType(T, 0); - return IntegerType.get()->getType().getUnqualifiedType(); + return cast(IntegerType)->getType().getUnqualifiedType(); } /// Set the underlying integer type. diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index a3447d1990975..82932e098c86f 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -271,16 +271,12 @@ class alignas(8) Decl { /// // LexicalDC == global namespace llvm::PointerUnion DeclCtx; - bool isInSemaDC() const { return DeclCtx.is(); } - bool isOutOfSemaDC() const { return DeclCtx.is(); } + bool isInSemaDC() const { return isa(DeclCtx); } + bool isOutOfSemaDC() const { return isa(DeclCtx); } - MultipleDC *getMultipleDC() const { - return DeclCtx.get(); - } + MultipleDC *getMultipleDC() const { return cast(DeclCtx); } - DeclContext *getSemanticDC() const { - return DeclCtx.get(); - } + DeclContext *getSemanticDC() const { return cast(DeclCtx); } /// Loc - The location of this decl. SourceLocation Loc; @@ -1340,7 +1336,7 @@ class DeclListNode { assert(Ptr && "dereferencing end() iterator"); if (DeclListNode *CurNode = Ptr.dyn_cast()) return CurNode->D; - return Ptr.get(); + return cast(Ptr); } void operator->() const { } // Unsupported. bool operator==(const iterator &X) const { return Ptr == X.Ptr; } diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index e389b5cd6df5b..c232556edeff7 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -2388,19 +2388,19 @@ class CXXCtorInitializer final { /// Determine whether this initializer is initializing a base class. bool isBaseInitializer() const { - return Initializee.is() && !IsDelegating; + return isa(Initializee) && !IsDelegating; } /// Determine whether this initializer is initializing a non-static /// data member. - bool isMemberInitializer() const { return Initializee.is(); } + bool isMemberInitializer() const { return isa(Initializee); } bool isAnyMemberInitializer() const { return isMemberInitializer() || isIndirectMemberInitializer(); } bool isIndirectMemberInitializer() const { - return Initializee.is(); + return isa(Initializee); } /// Determine whether this initializer is an implicit initializer @@ -2416,7 +2416,7 @@ class CXXCtorInitializer final { /// Determine whether this initializer is creating a delegating /// constructor. bool isDelegatingInitializer() const { - return Initializee.is() && IsDelegating; + return isa(Initializee) && IsDelegating; } /// Determine whether this initializer is a pack expansion. @@ -2457,21 +2457,21 @@ class CXXCtorInitializer final { /// non-static data member being initialized. Otherwise, returns null. FieldDecl *getMember() const { if (isMemberInitializer()) - return Initializee.get(); + return cast(Initializee); return nullptr; } FieldDecl *getAnyMember() const { if (isMemberInitializer()) - return Initializee.get(); + return cast(Initializee); if (isIndirectMemberInitializer()) - return Initializee.get()->getAnonField(); + return cast(Initializee)->getAnonField(); return nullptr; } IndirectFieldDecl *getIndirectMember() const { if (isIndirectMemberInitializer()) - return Initializee.get(); + return cast(Initializee); return nullptr; } diff --git a/clang/include/clang/AST/DeclContextInternals.h b/clang/include/clang/AST/DeclContextInternals.h index e169c48592192..b17b7627ac90c 100644 --- a/clang/include/clang/AST/DeclContextInternals.h +++ b/clang/include/clang/AST/DeclContextInternals.h @@ -70,7 +70,7 @@ class StoredDeclsList { // want to keep (if any) will be of the form DeclListNode(D, ); // replace it with just D. if (NewLast) { - DeclListNode *Node = NewLast->get(); + DeclListNode *Node = cast(*NewLast); *NewLast = Node->D; C.DeallocateDeclListNode(Node); } @@ -84,11 +84,11 @@ class StoredDeclsList { if (!Data.getPointer()) // All declarations are erased. return nullptr; - else if (NewHead.is()) + else if (isa(NewHead)) // The list only contains a declaration, the header itself. return (DeclListNode::Decls *)&Data; else { - assert(NewLast && NewLast->is() && "Not the tail?"); + assert(NewLast && isa(*NewLast) && "Not the tail?"); return NewLast; } } @@ -207,7 +207,7 @@ class StoredDeclsList { } // Append the Decls. - DeclListNode *Node = C.AllocateDeclListNode(Tail->get()); + DeclListNode *Node = C.AllocateDeclListNode(cast(*Tail)); Node->Rest = DeclsAsList; *Tail = Node; } @@ -293,7 +293,7 @@ class StoredDeclsList { llvm::errs() << '[' << Node->D << "] -> "; D = Node->Rest; } else { - llvm::errs() << '[' << D.get() << "]\n"; + llvm::errs() << '[' << cast(D) << "]\n"; return; } } diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h index e4bf54c3d77b7..d3a466a8617bb 100644 --- a/clang/include/clang/AST/DeclTemplate.h +++ b/clang/include/clang/AST/DeclTemplate.h @@ -319,8 +319,7 @@ class DefaultArgStorage { const DefaultArgStorage &Storage = Parm->getDefaultArgStorage(); if (auto *Prev = Storage.ValueOrInherited.template dyn_cast()) Parm = Prev; - assert(!Parm->getDefaultArgStorage() - .ValueOrInherited.template is() && + assert(!isa(Parm->getDefaultArgStorage().ValueOrInherited) && "should only be one level of indirection"); return Parm; } @@ -333,7 +332,7 @@ class DefaultArgStorage { /// Determine whether the default argument for this parameter was inherited /// from a previous declaration of the same entity. - bool isInherited() const { return ValueOrInherited.template is(); } + bool isInherited() const { return isa(ValueOrInherited); } /// Get the default argument's value. This does not consider whether the /// default argument is visible. @@ -343,7 +342,7 @@ class DefaultArgStorage { Storage = &Prev->getDefaultArgStorage(); if (const auto *C = Storage->ValueOrInherited.template dyn_cast()) return C->Value; - return Storage->ValueOrInherited.template get(); + return cast(Storage->ValueOrInherited); } /// Get the parameter from which we inherit the default argument, if any. @@ -379,7 +378,7 @@ class DefaultArgStorage { Inherited->PrevDeclWithDefaultArg = InheritedFrom; } else ValueOrInherited = new (allocateDefaultArgStorageChain(C)) - Chain{InheritedFrom, ValueOrInherited.template get()}; + Chain{InheritedFrom, cast(ValueOrInherited)}; } /// Remove the default argument, even if it was inherited. @@ -735,6 +734,7 @@ class RedeclarableTemplateDecl : public TemplateDecl, } void anchor() override; + protected: template struct SpecEntryTraits { using DeclType = EntryType; @@ -775,13 +775,22 @@ class RedeclarableTemplateDecl : public TemplateDecl, return SpecIterator(isEnd ? Specs.end() : Specs.begin()); } - void loadLazySpecializationsImpl() const; + void loadLazySpecializationsImpl(bool OnlyPartial = false) const; + + bool loadLazySpecializationsImpl(llvm::ArrayRef Args, + TemplateParameterList *TPL = nullptr) const; template typename SpecEntryTraits::DeclType* findSpecializationImpl(llvm::FoldingSetVector &Specs, void *&InsertPos, ProfileArguments &&...ProfileArgs); + template + typename SpecEntryTraits::DeclType * + findSpecializationLocally(llvm::FoldingSetVector &Specs, + void *&InsertPos, + ProfileArguments &&...ProfileArgs); + template void addSpecializationImpl(llvm::FoldingSetVector &Specs, EntryType *Entry, void *InsertPos); @@ -796,13 +805,6 @@ class RedeclarableTemplateDecl : public TemplateDecl, /// was explicitly specialized. llvm::PointerIntPair InstantiatedFromMember; - - /// If non-null, points to an array of specializations (including - /// partial specializations) known only by their external declaration IDs. - /// - /// The first value in the array is the number of specializations/partial - /// specializations that follow. - GlobalDeclID *LazySpecializations = nullptr; }; /// Pointer to the common data shared by all declarations of this @@ -1962,7 +1964,7 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, SpecializedTemplate.dyn_cast()) return PartialSpec->PartialSpecialization; - return SpecializedTemplate.get(); + return cast(SpecializedTemplate); } /// Retrieve the set of template arguments that should be used @@ -1989,7 +1991,7 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, /// template arguments have been deduced. void setInstantiationOf(ClassTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs) { - assert(!SpecializedTemplate.is() && + assert(!isa(SpecializedTemplate) && "Already set to a class template partial specialization!"); auto *PS = new (getASTContext()) SpecializedPartialSpecialization(); PS->PartialSpecialization = PartialSpec; @@ -2000,7 +2002,7 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, /// Note that this class template specialization is an instantiation /// of the given class template. void setInstantiationOf(ClassTemplateDecl *TemplDecl) { - assert(!SpecializedTemplate.is() && + assert(!isa(SpecializedTemplate) && "Previously set to a class template partial specialization!"); SpecializedTemplate = TemplDecl; } @@ -2010,7 +2012,7 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl, const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { if (auto *Info = ExplicitInfo.dyn_cast()) return Info->TemplateArgsAsWritten; - return ExplicitInfo.get(); + return cast(ExplicitInfo); } /// Set the template argument list as written in the sources. @@ -2283,7 +2285,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl { friend class TemplateDeclInstantiator; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying class declarations of the template. CXXRecordDecl *getTemplatedDecl() const { @@ -2731,7 +2733,7 @@ class VarTemplateSpecializationDecl : public VarDecl, SpecializedTemplate.dyn_cast()) return PartialSpec->PartialSpecialization; - return SpecializedTemplate.get(); + return cast(SpecializedTemplate); } /// Retrieve the set of template arguments that should be used @@ -2758,7 +2760,7 @@ class VarTemplateSpecializationDecl : public VarDecl, /// template arguments have been deduced. void setInstantiationOf(VarTemplatePartialSpecializationDecl *PartialSpec, const TemplateArgumentList *TemplateArgs) { - assert(!SpecializedTemplate.is() && + assert(!isa(SpecializedTemplate) && "Already set to a variable template partial specialization!"); auto *PS = new (getASTContext()) SpecializedPartialSpecialization(); PS->PartialSpecialization = PartialSpec; @@ -2769,7 +2771,7 @@ class VarTemplateSpecializationDecl : public VarDecl, /// Note that this variable template specialization is an instantiation /// of the given variable template. void setInstantiationOf(VarTemplateDecl *TemplDecl) { - assert(!SpecializedTemplate.is() && + assert(!isa(SpecializedTemplate) && "Previously set to a variable template partial specialization!"); SpecializedTemplate = TemplDecl; } @@ -2779,7 +2781,7 @@ class VarTemplateSpecializationDecl : public VarDecl, const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const { if (auto *Info = ExplicitInfo.dyn_cast()) return Info->TemplateArgsAsWritten; - return ExplicitInfo.get(); + return cast(ExplicitInfo); } /// Set the template argument list as written in the sources. @@ -3033,7 +3035,7 @@ class VarTemplateDecl : public RedeclarableTemplateDecl { friend class ASTDeclWriter; /// Load any lazily-loaded specializations from the external source. - void LoadLazySpecializations() const; + void LoadLazySpecializations(bool OnlyPartial = false) const; /// Get the underlying variable declarations of the template. VarDecl *getTemplatedDecl() const { @@ -3306,7 +3308,7 @@ inline NamedDecl *getAsNamedDecl(TemplateParameter P) { return PD; if (auto *PD = P.dyn_cast()) return PD; - return P.get(); + return cast(P); } inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) { diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 1a24b8857674c..4cec89c979f77 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -878,7 +878,7 @@ class CXXTypeidExpr : public Expr { /// object. This is not a strong guarantee. bool isMostDerived(const ASTContext &Context) const; - bool isTypeOperand() const { return Operand.is(); } + bool isTypeOperand() const { return isa(Operand); } /// Retrieves the type operand of this typeid() expression after /// various required adjustments (removing reference types, cv-qualifiers). @@ -887,11 +887,11 @@ class CXXTypeidExpr : public Expr { /// Retrieve source information for the type operand. TypeSourceInfo *getTypeOperandSourceInfo() const { assert(isTypeOperand() && "Cannot call getTypeOperand for typeid(expr)"); - return Operand.get(); + return cast(Operand); } Expr *getExprOperand() const { assert(!isTypeOperand() && "Cannot call getExprOperand for typeid(type)"); - return static_cast(Operand.get()); + return static_cast(cast(Operand)); } SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } @@ -1093,7 +1093,7 @@ class CXXUuidofExpr : public Expr { Operand = (TypeSourceInfo*)nullptr; } - bool isTypeOperand() const { return Operand.is(); } + bool isTypeOperand() const { return isa(Operand); } /// Retrieves the type operand of this __uuidof() expression after /// various required adjustments (removing reference types, cv-qualifiers). @@ -1102,11 +1102,11 @@ class CXXUuidofExpr : public Expr { /// Retrieve source information for the type operand. TypeSourceInfo *getTypeOperandSourceInfo() const { assert(isTypeOperand() && "Cannot call getTypeOperand for __uuidof(expr)"); - return Operand.get(); + return cast(Operand); } Expr *getExprOperand() const { assert(!isTypeOperand() && "Cannot call getExprOperand for __uuidof(type)"); - return static_cast(Operand.get()); + return static_cast(cast(Operand)); } MSGuidDecl *getGuidDecl() const { return Guid; } @@ -4750,24 +4750,24 @@ class MaterializeTemporaryExpr : public Expr { /// be materialized into a glvalue. Expr *getSubExpr() const { return cast( - State.is() - ? State.get() - : State.get()->getTemporaryExpr()); + isa(State) + ? cast(State) + : cast(State)->getTemporaryExpr()); } /// Retrieve the storage duration for the materialized temporary. StorageDuration getStorageDuration() const { - return State.is() ? SD_FullExpression - : State.get() + return isa(State) ? SD_FullExpression + : cast(State) ->getStorageDuration(); } /// Get the storage for the constant value of a materialized temporary /// of static storage duration. APValue *getOrCreateValue(bool MayCreate) const { - assert(State.is() && + assert(isa(State) && "the temporary has not been lifetime extended"); - return State.get()->getOrCreateValue( + return cast(State)->getOrCreateValue( MayCreate); } @@ -4782,8 +4782,8 @@ class MaterializeTemporaryExpr : public Expr { /// Get the declaration which triggered the lifetime-extension of this /// temporary, if any. ValueDecl *getExtendingDecl() { - return State.is() ? nullptr - : State.get() + return isa(State) ? nullptr + : cast(State) ->getExtendingDecl(); } const ValueDecl *getExtendingDecl() const { @@ -4793,8 +4793,8 @@ class MaterializeTemporaryExpr : public Expr { void setExtendingDecl(ValueDecl *ExtendedBy, unsigned ManglingNumber); unsigned getManglingNumber() const { - return State.is() ? 0 - : State.get() + return isa(State) ? 0 + : cast(State) ->getManglingNumber(); } @@ -4820,17 +4820,17 @@ class MaterializeTemporaryExpr : public Expr { // Iterators child_range children() { - return State.is() + return isa(State) ? child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1) - : State.get()->childrenExpr(); + : cast(State)->childrenExpr(); } const_child_range children() const { - return State.is() + return isa(State) ? const_child_range(State.getAddrOfPtr1(), State.getAddrOfPtr1() + 1) : const_cast( - State.get()) + cast(State)) ->childrenExpr(); } }; diff --git a/clang/include/clang/AST/ExprConcepts.h b/clang/include/clang/AST/ExprConcepts.h index f3e32ce396198..f988d40cf73c3 100644 --- a/clang/include/clang/AST/ExprConcepts.h +++ b/clang/include/clang/AST/ExprConcepts.h @@ -261,13 +261,13 @@ class TypeRequirement : public Requirement { assert(Status == SS_SubstitutionFailure && "Attempted to get substitution diagnostic when there has been no " "substitution failure."); - return Value.get(); + return cast(Value); } TypeSourceInfo *getType() const { assert(!isSubstitutionFailure() && "Attempted to get type when there has been a substitution failure."); - return Value.get(); + return cast(Value); } static bool classof(const Requirement *R) { @@ -329,24 +329,24 @@ class ExprRequirement : public Requirement { bool isSubstitutionFailure() const { return !isEmpty() && - TypeConstraintInfo.getPointer().is(); + isa(TypeConstraintInfo.getPointer()); } bool isTypeConstraint() const { return !isEmpty() && - TypeConstraintInfo.getPointer().is(); + isa(TypeConstraintInfo.getPointer()); } SubstitutionDiagnostic *getSubstitutionDiagnostic() const { assert(isSubstitutionFailure()); - return TypeConstraintInfo.getPointer().get(); + return cast(TypeConstraintInfo.getPointer()); } const TypeConstraint *getTypeConstraint() const; TemplateParameterList *getTypeConstraintTemplateParameterList() const { assert(isTypeConstraint()); - return TypeConstraintInfo.getPointer().get(); + return cast(TypeConstraintInfo.getPointer()); } }; private: @@ -409,14 +409,14 @@ class ExprRequirement : public Requirement { assert(isExprSubstitutionFailure() && "Attempted to get expression substitution diagnostic when there has " "been no expression substitution failure"); - return Value.get(); + return cast(Value); } Expr *getExpr() const { assert(!isExprSubstitutionFailure() && "ExprRequirement has no expression because there has been a " "substitution failure."); - return Value.get(); + return cast(Value); } static bool classof(const Requirement *R) { diff --git a/clang/include/clang/AST/ExprObjC.h b/clang/include/clang/AST/ExprObjC.h index f833916c91aa5..1fccc26069582 100644 --- a/clang/include/clang/AST/ExprObjC.h +++ b/clang/include/clang/AST/ExprObjC.h @@ -752,28 +752,24 @@ class ObjCPropertyRefExpr : public Expr { setMethodRefFlag(MethodRef_Setter, val); } - const Expr *getBase() const { - return cast(Receiver.get()); - } - Expr *getBase() { - return cast(Receiver.get()); - } + const Expr *getBase() const { return cast(cast(Receiver)); } + Expr *getBase() { return cast(cast(Receiver)); } SourceLocation getLocation() const { return IdLoc; } SourceLocation getReceiverLocation() const { return ReceiverLoc; } QualType getSuperReceiverType() const { - return QualType(Receiver.get(), 0); + return QualType(cast(Receiver), 0); } ObjCInterfaceDecl *getClassReceiver() const { - return Receiver.get(); + return cast(Receiver); } - bool isObjectReceiver() const { return Receiver.is(); } - bool isSuperReceiver() const { return Receiver.is(); } - bool isClassReceiver() const { return Receiver.is(); } + bool isObjectReceiver() const { return isa(Receiver); } + bool isSuperReceiver() const { return isa(Receiver); } + bool isClassReceiver() const { return isa(Receiver); } /// Determine the type of the base, regardless of the kind of receiver. QualType getReceiverType(const ASTContext &ctx) const; @@ -787,7 +783,7 @@ class ObjCPropertyRefExpr : public Expr { // Iterators child_range children() { - if (Receiver.is()) { + if (isa(Receiver)) { Stmt **begin = reinterpret_cast(&Receiver); // hack! return child_range(begin, begin+1); } diff --git a/clang/include/clang/AST/ExternalASTSource.h b/clang/include/clang/AST/ExternalASTSource.h index 582ed7c65f58c..4d7ff822fceb7 100644 --- a/clang/include/clang/AST/ExternalASTSource.h +++ b/clang/include/clang/AST/ExternalASTSource.h @@ -152,6 +152,21 @@ class ExternalASTSource : public RefCountedBase { virtual bool FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name); + /// Load all the external specializations for the Decl \param D if \param + /// OnlyPartial is false. Otherwise, load all the external **partial** + /// specializations for the \param D. + /// + /// Return true if any new specializations get loaded. Return false otherwise. + virtual bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial); + + /// Load all the specializations for the Decl \param D with the same template + /// args specified by \param TemplateArgs. + /// + /// Return true if any new specializations get loaded. Return false otherwise. + virtual bool + LoadExternalSpecializations(const Decl *D, + ArrayRef TemplateArgs); + /// Ensures that the table of all visible declarations inside this /// context is up to date. /// @@ -447,9 +462,7 @@ struct LazyGenerationalUpdatePtr { : Value(Value) {} /// Forcibly set this pointer (which must be lazy) as needing updates. - void markIncomplete() { - Value.template get()->LastGeneration = 0; - } + void markIncomplete() { cast(Value)->LastGeneration = 0; } /// Set the value of this pointer, in the current generation. void set(T NewValue) { @@ -472,14 +485,14 @@ struct LazyGenerationalUpdatePtr { } return LazyVal->LastValue; } - return Value.template get(); + return cast(Value); } /// Get the most recently computed value of this pointer without updating it. T getNotUpdated() const { if (auto *LazyVal = Value.template dyn_cast()) return LazyVal->LastValue; - return Value.template get(); + return cast(Value); } void *getOpaqueValue() { return Value.getOpaqueValue(); } diff --git a/clang/include/clang/AST/OpenACCClause.h b/clang/include/clang/AST/OpenACCClause.h index 5ad4c336b6c53..51db58d484a25 100644 --- a/clang/include/clang/AST/OpenACCClause.h +++ b/clang/include/clang/AST/OpenACCClause.h @@ -38,7 +38,7 @@ class OpenACCClause { SourceLocation getBeginLoc() const { return Location.getBegin(); } SourceLocation getEndLoc() const { return Location.getEnd(); } - static bool classof(const OpenACCClause *) { return false; } + static bool classof(const OpenACCClause *) { return true; } using child_iterator = StmtIterator; using const_child_iterator = ConstStmtIterator; @@ -76,6 +76,50 @@ class OpenACCAutoClause : public OpenACCClause { } }; +// Represents the 'finalize' clause. +class OpenACCFinalizeClause : public OpenACCClause { +protected: + OpenACCFinalizeClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::Finalize, BeginLoc, EndLoc) {} + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Finalize; + } + + static OpenACCFinalizeClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + +// Represents the 'if_present' clause. +class OpenACCIfPresentClause : public OpenACCClause { +protected: + OpenACCIfPresentClause(SourceLocation BeginLoc, SourceLocation EndLoc) + : OpenACCClause(OpenACCClauseKind::IfPresent, BeginLoc, EndLoc) {} + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::IfPresent; + } + + static OpenACCIfPresentClause * + Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation EndLoc); + + child_range children() { + return child_range(child_iterator(), child_iterator()); + } + const_child_range children() const { + return const_child_range(const_child_iterator(), const_child_iterator()); + } +}; + // Represents the 'independent' clause. class OpenACCIndependentClause : public OpenACCClause { protected: @@ -147,8 +191,9 @@ using DeviceTypeArgument = std::pair; /// an identifier. The 'asterisk' means 'the rest'. class OpenACCDeviceTypeClause final : public OpenACCClauseWithParams, - public llvm::TrailingObjects { + friend TrailingObjects; // Data stored in trailing objects as IdentifierInfo* /SourceLocation pairs. A // nullptr IdentifierInfo* represents an asterisk. unsigned NumArchs; @@ -333,7 +378,8 @@ class OpenACCClauseWithExprs : public OpenACCClauseWithParams { // Represents the 'devnum' and expressions lists for the 'wait' clause. class OpenACCWaitClause final : public OpenACCClauseWithExprs, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; SourceLocation QueuesLoc; OpenACCWaitClause(SourceLocation BeginLoc, SourceLocation LParenLoc, Expr *DevNumExpr, SourceLocation QueuesLoc, @@ -375,7 +421,8 @@ class OpenACCWaitClause final class OpenACCNumGangsClause final : public OpenACCClauseWithExprs, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; OpenACCNumGangsClause(SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef IntExprs, SourceLocation EndLoc) @@ -405,7 +452,8 @@ class OpenACCNumGangsClause final class OpenACCTileClause final : public OpenACCClauseWithExprs, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; OpenACCTileClause(SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef SizeExprs, SourceLocation EndLoc) : OpenACCClauseWithExprs(OpenACCClauseKind::Tile, BeginLoc, LParenLoc, @@ -459,7 +507,8 @@ class OpenACCClauseWithSingleIntExpr : public OpenACCClauseWithExprs { class OpenACCGangClause final : public OpenACCClauseWithExprs, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; protected: OpenACCGangClause(SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef GangKinds, @@ -483,6 +532,14 @@ class OpenACCGangClause final return {getGangKind(I), getExprs()[I]}; } + bool hasExprOfKind(OpenACCGangKind GK) const { + for (unsigned I = 0; I < getNumExprs(); ++I) { + if (getGangKind(I) == GK) + return true; + } + return false; + } + static OpenACCGangClause * Create(const ASTContext &Ctx, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef GangKinds, @@ -606,7 +663,8 @@ class OpenACCClauseWithVarList : public OpenACCClauseWithExprs { class OpenACCPrivateClause final : public OpenACCClauseWithVarList, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; OpenACCPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef VarList, SourceLocation EndLoc) @@ -628,7 +686,8 @@ class OpenACCPrivateClause final class OpenACCFirstPrivateClause final : public OpenACCClauseWithVarList, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; OpenACCFirstPrivateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef VarList, SourceLocation EndLoc) @@ -650,7 +709,8 @@ class OpenACCFirstPrivateClause final class OpenACCDevicePtrClause final : public OpenACCClauseWithVarList, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; OpenACCDevicePtrClause(SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef VarList, SourceLocation EndLoc) @@ -672,7 +732,8 @@ class OpenACCDevicePtrClause final class OpenACCAttachClause final : public OpenACCClauseWithVarList, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; OpenACCAttachClause(SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef VarList, SourceLocation EndLoc) @@ -692,9 +753,79 @@ class OpenACCAttachClause final ArrayRef VarList, SourceLocation EndLoc); }; +class OpenACCDetachClause final + : public OpenACCClauseWithVarList, + private llvm::TrailingObjects { + friend TrailingObjects; + + OpenACCDetachClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(OpenACCClauseKind::Detach, BeginLoc, LParenLoc, + EndLoc) { + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Detach; + } + static OpenACCDetachClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc); +}; + +class OpenACCDeleteClause final + : public OpenACCClauseWithVarList, + private llvm::TrailingObjects { + friend TrailingObjects; + + OpenACCDeleteClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(OpenACCClauseKind::Delete, BeginLoc, LParenLoc, + EndLoc) { + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::Delete; + } + static OpenACCDeleteClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc); +}; + +class OpenACCUseDeviceClause final + : public OpenACCClauseWithVarList, + private llvm::TrailingObjects { + friend TrailingObjects; + + OpenACCUseDeviceClause(SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc) + : OpenACCClauseWithVarList(OpenACCClauseKind::UseDevice, BeginLoc, + LParenLoc, EndLoc) { + std::uninitialized_copy(VarList.begin(), VarList.end(), + getTrailingObjects()); + setExprs(MutableArrayRef(getTrailingObjects(), VarList.size())); + } + +public: + static bool classof(const OpenACCClause *C) { + return C->getClauseKind() == OpenACCClauseKind::UseDevice; + } + static OpenACCUseDeviceClause * + Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, + ArrayRef VarList, SourceLocation EndLoc); +}; + class OpenACCNoCreateClause final : public OpenACCClauseWithVarList, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; OpenACCNoCreateClause(SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef VarList, SourceLocation EndLoc) @@ -716,7 +847,8 @@ class OpenACCNoCreateClause final class OpenACCPresentClause final : public OpenACCClauseWithVarList, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; OpenACCPresentClause(SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef VarList, SourceLocation EndLoc) @@ -738,7 +870,8 @@ class OpenACCPresentClause final class OpenACCCopyClause final : public OpenACCClauseWithVarList, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; OpenACCCopyClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef VarList, @@ -767,7 +900,8 @@ class OpenACCCopyClause final class OpenACCCopyInClause final : public OpenACCClauseWithVarList, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; bool IsReadOnly; OpenACCCopyInClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, @@ -799,7 +933,8 @@ class OpenACCCopyInClause final class OpenACCCopyOutClause final : public OpenACCClauseWithVarList, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; bool IsZero; OpenACCCopyOutClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, @@ -831,7 +966,8 @@ class OpenACCCopyOutClause final class OpenACCCreateClause final : public OpenACCClauseWithVarList, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; bool IsZero; OpenACCCreateClause(OpenACCClauseKind Spelling, SourceLocation BeginLoc, @@ -863,7 +999,8 @@ class OpenACCCreateClause final class OpenACCReductionClause final : public OpenACCClauseWithVarList, - public llvm::TrailingObjects { + private llvm::TrailingObjects { + friend TrailingObjects; OpenACCReductionOperator Op; OpenACCReductionClause(SourceLocation BeginLoc, SourceLocation LParenLoc, diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 76b598a5db238..5d5c91ff91d55 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -2151,8 +2151,11 @@ DEF_TRAVERSE_DECL(DecompositionDecl, { }) DEF_TRAVERSE_DECL(BindingDecl, { - if (getDerived().shouldVisitImplicitCode()) + if (getDerived().shouldVisitImplicitCode()) { TRY_TO(TraverseStmt(D->getBinding())); + if (const auto HoldingVar = D->getHoldingVar()) + TRY_TO(TraverseDecl(HoldingVar)); + } }) DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); }) @@ -4058,6 +4061,12 @@ DEF_TRAVERSE_STMT(OpenACCLoopConstruct, { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); }) DEF_TRAVERSE_STMT(OpenACCCombinedConstruct, { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); }) +DEF_TRAVERSE_STMT(OpenACCDataConstruct, + { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); }) +DEF_TRAVERSE_STMT(OpenACCEnterDataConstruct, {}) +DEF_TRAVERSE_STMT(OpenACCExitDataConstruct, {}) +DEF_TRAVERSE_STMT(OpenACCHostDataConstruct, + { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); }) // Traverse HLSL: Out argument expression DEF_TRAVERSE_STMT(HLSLOutArgExpr, {}) diff --git a/clang/include/clang/AST/Redeclarable.h b/clang/include/clang/AST/Redeclarable.h index 8d320a9ced279..ee21f11e5f707 100644 --- a/clang/include/clang/AST/Redeclarable.h +++ b/clang/include/clang/AST/Redeclarable.h @@ -113,25 +113,24 @@ class Redeclarable { DeclLink(PreviousTag, decl_type *D) : Link(NotKnownLatest(Previous(D))) {} bool isFirst() const { - return Link.is() || + return isa(Link) || // FIXME: 'template' is required on the next line due to an // apparent clang bug. - Link.get().template is(); + isa(cast(Link)); } decl_type *getPrevious(const decl_type *D) const { - if (Link.is()) { - NotKnownLatest NKL = Link.get(); - if (NKL.is()) - return static_cast(NKL.get()); + if (NotKnownLatest NKL = dyn_cast(Link)) { + if (auto *Prev = dyn_cast(NKL)) + return static_cast(Prev); // Allocate the generational 'most recent' cache now, if needed. Link = KnownLatest(*reinterpret_cast( - NKL.get()), + cast(NKL)), const_cast(D)); } - return static_cast(Link.get().get(D)); + return static_cast(cast(Link).get(D)); } void setPrevious(decl_type *D) { @@ -141,25 +140,24 @@ class Redeclarable { void setLatest(decl_type *D) { assert(isFirst() && "decl became canonical unexpectedly"); - if (Link.is()) { - NotKnownLatest NKL = Link.get(); + if (NotKnownLatest NKL = dyn_cast(Link)) { Link = KnownLatest(*reinterpret_cast( - NKL.get()), + cast(NKL)), D); } else { - auto Latest = Link.get(); + auto Latest = cast(Link); Latest.set(D); Link = Latest; } } - void markIncomplete() { Link.get().markIncomplete(); } + void markIncomplete() { cast(Link).markIncomplete(); } Decl *getLatestNotUpdated() const { assert(isFirst() && "expected a canonical decl"); - if (Link.is()) + if (isa(Link)) return nullptr; - return Link.get().getNotUpdated(); + return cast(Link).getNotUpdated(); } }; diff --git a/clang/include/clang/AST/StmtOpenACC.h b/clang/include/clang/AST/StmtOpenACC.h index fa8793e740822..a1903cd9e3a23 100644 --- a/clang/include/clang/AST/StmtOpenACC.h +++ b/clang/include/clang/AST/StmtOpenACC.h @@ -127,11 +127,12 @@ class OpenACCAssociatedStmtConstruct : public OpenACCConstructStmt { /// the 'Kind'. class OpenACCComputeConstruct final : public OpenACCAssociatedStmtConstruct, - public llvm::TrailingObjects { + private llvm::TrailingObjects { friend class ASTStmtWriter; friend class ASTStmtReader; friend class ASTContext; + friend TrailingObjects; OpenACCComputeConstruct(unsigned NumClauses) : OpenACCAssociatedStmtConstruct( OpenACCComputeConstructClass, OpenACCDirectiveKind::Invalid, @@ -189,7 +190,7 @@ class OpenACCComputeConstruct final /// Construct. class OpenACCLoopConstruct final : public OpenACCAssociatedStmtConstruct, - public llvm::TrailingObjects { // The compute/combined construct kind this loop is associated with, or // invalid if this is an orphaned loop construct. @@ -202,6 +203,7 @@ class OpenACCLoopConstruct final friend class OpenACCAssociatedStmtConstruct; friend class OpenACCCombinedConstruct; friend class OpenACCComputeConstruct; + friend TrailingObjects; OpenACCLoopConstruct(unsigned NumClauses); @@ -245,8 +247,9 @@ class OpenACCLoopConstruct final // shared with both loop and compute constructs. class OpenACCCombinedConstruct final : public OpenACCAssociatedStmtConstruct, - public llvm::TrailingObjects { + friend TrailingObjects; OpenACCCombinedConstruct(unsigned NumClauses) : OpenACCAssociatedStmtConstruct( OpenACCCombinedConstructClass, OpenACCDirectiveKind::Invalid, @@ -292,5 +295,179 @@ class OpenACCCombinedConstruct final return const_cast(this)->getLoop(); } }; + +// This class represents a 'data' construct, which has an associated statement +// and clauses, but is otherwise pretty simple. +class OpenACCDataConstruct final + : public OpenACCAssociatedStmtConstruct, + private llvm::TrailingObjects { + friend TrailingObjects; + OpenACCDataConstruct(unsigned NumClauses) + : OpenACCAssociatedStmtConstruct( + OpenACCDataConstructClass, OpenACCDirectiveKind::Data, + SourceLocation{}, SourceLocation{}, SourceLocation{}, + /*AssociatedStmt=*/nullptr) { + std::uninitialized_value_construct( + getTrailingObjects(), + getTrailingObjects() + NumClauses); + setClauseList(MutableArrayRef(getTrailingObjects(), + NumClauses)); + } + + OpenACCDataConstruct(SourceLocation Start, SourceLocation DirectiveLoc, + SourceLocation End, + ArrayRef Clauses, + Stmt *StructuredBlock) + : OpenACCAssociatedStmtConstruct(OpenACCDataConstructClass, + OpenACCDirectiveKind::Data, Start, + DirectiveLoc, End, StructuredBlock) { + std::uninitialized_copy(Clauses.begin(), Clauses.end(), + getTrailingObjects()); + setClauseList(MutableArrayRef(getTrailingObjects(), + Clauses.size())); + } + void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); } + +public: + static bool classof(const Stmt *T) { + return T->getStmtClass() == OpenACCDataConstructClass; + } + + static OpenACCDataConstruct *CreateEmpty(const ASTContext &C, + unsigned NumClauses); + static OpenACCDataConstruct *Create(const ASTContext &C, SourceLocation Start, + SourceLocation DirectiveLoc, + SourceLocation End, + ArrayRef Clauses, + Stmt *StructuredBlock); + Stmt *getStructuredBlock() { return getAssociatedStmt(); } + const Stmt *getStructuredBlock() const { + return const_cast(this)->getStructuredBlock(); + } +}; +// This class represents a 'enter data' construct, which JUST has clauses. +class OpenACCEnterDataConstruct final + : public OpenACCConstructStmt, + private llvm::TrailingObjects { + friend TrailingObjects; + OpenACCEnterDataConstruct(unsigned NumClauses) + : OpenACCConstructStmt(OpenACCEnterDataConstructClass, + OpenACCDirectiveKind::EnterData, SourceLocation{}, + SourceLocation{}, SourceLocation{}) { + std::uninitialized_value_construct( + getTrailingObjects(), + getTrailingObjects() + NumClauses); + setClauseList(MutableArrayRef(getTrailingObjects(), + NumClauses)); + } + OpenACCEnterDataConstruct(SourceLocation Start, SourceLocation DirectiveLoc, + SourceLocation End, + ArrayRef Clauses) + : OpenACCConstructStmt(OpenACCEnterDataConstructClass, + OpenACCDirectiveKind::EnterData, Start, + DirectiveLoc, End) { + std::uninitialized_copy(Clauses.begin(), Clauses.end(), + getTrailingObjects()); + setClauseList(MutableArrayRef(getTrailingObjects(), + Clauses.size())); + } + +public: + static bool classof(const Stmt *T) { + return T->getStmtClass() == OpenACCEnterDataConstructClass; + } + static OpenACCEnterDataConstruct *CreateEmpty(const ASTContext &C, + unsigned NumClauses); + static OpenACCEnterDataConstruct * + Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, + SourceLocation End, ArrayRef Clauses); +}; +// This class represents a 'exit data' construct, which JUST has clauses. +class OpenACCExitDataConstruct final + : public OpenACCConstructStmt, + private llvm::TrailingObjects { + friend TrailingObjects; + OpenACCExitDataConstruct(unsigned NumClauses) + : OpenACCConstructStmt(OpenACCExitDataConstructClass, + OpenACCDirectiveKind::ExitData, SourceLocation{}, + SourceLocation{}, SourceLocation{}) { + std::uninitialized_value_construct( + getTrailingObjects(), + getTrailingObjects() + NumClauses); + setClauseList(MutableArrayRef(getTrailingObjects(), + NumClauses)); + } + OpenACCExitDataConstruct(SourceLocation Start, SourceLocation DirectiveLoc, + SourceLocation End, + ArrayRef Clauses) + : OpenACCConstructStmt(OpenACCExitDataConstructClass, + OpenACCDirectiveKind::ExitData, Start, + DirectiveLoc, End) { + std::uninitialized_copy(Clauses.begin(), Clauses.end(), + getTrailingObjects()); + setClauseList(MutableArrayRef(getTrailingObjects(), + Clauses.size())); + } + +public: + static bool classof(const Stmt *T) { + return T->getStmtClass() == OpenACCExitDataConstructClass; + } + static OpenACCExitDataConstruct *CreateEmpty(const ASTContext &C, + unsigned NumClauses); + static OpenACCExitDataConstruct * + Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, + SourceLocation End, ArrayRef Clauses); +}; +// This class represents a 'host_data' construct, which has an associated +// statement and clauses, but is otherwise pretty simple. +class OpenACCHostDataConstruct final + : public OpenACCAssociatedStmtConstruct, + private llvm::TrailingObjects { + friend TrailingObjects; + OpenACCHostDataConstruct(unsigned NumClauses) + : OpenACCAssociatedStmtConstruct( + OpenACCHostDataConstructClass, OpenACCDirectiveKind::HostData, + SourceLocation{}, SourceLocation{}, SourceLocation{}, + /*AssociatedStmt=*/nullptr) { + std::uninitialized_value_construct( + getTrailingObjects(), + getTrailingObjects() + NumClauses); + setClauseList(MutableArrayRef(getTrailingObjects(), + NumClauses)); + } + OpenACCHostDataConstruct(SourceLocation Start, SourceLocation DirectiveLoc, + SourceLocation End, + ArrayRef Clauses, + Stmt *StructuredBlock) + : OpenACCAssociatedStmtConstruct(OpenACCHostDataConstructClass, + OpenACCDirectiveKind::HostData, Start, + DirectiveLoc, End, StructuredBlock) { + std::uninitialized_copy(Clauses.begin(), Clauses.end(), + getTrailingObjects()); + setClauseList(MutableArrayRef(getTrailingObjects(), + Clauses.size())); + } + void setStructuredBlock(Stmt *S) { setAssociatedStmt(S); } + +public: + static bool classof(const Stmt *T) { + return T->getStmtClass() == OpenACCHostDataConstructClass; + } + static OpenACCHostDataConstruct *CreateEmpty(const ASTContext &C, + unsigned NumClauses); + static OpenACCHostDataConstruct * + Create(const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, + SourceLocation End, ArrayRef Clauses, + Stmt *StructuredBlock); + Stmt *getStructuredBlock() { return getAssociatedStmt(); } + const Stmt *getStructuredBlock() const { + return const_cast(this)->getStructuredBlock(); + } +}; } // namespace clang #endif // LLVM_CLANG_AST_STMTOPENACC_H diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h index a8f0263d5505a..9d0ee24a4f5e3 100644 --- a/clang/include/clang/AST/TemplateBase.h +++ b/clang/include/clang/AST/TemplateBase.h @@ -484,7 +484,7 @@ struct TemplateArgumentLocInfo { Pointer; TemplateTemplateArgLocInfo *getTemplate() const { - return Pointer.get(); + return cast(Pointer); } public: @@ -499,10 +499,10 @@ struct TemplateArgumentLocInfo { SourceLocation EllipsisLoc); TypeSourceInfo *getAsTypeSourceInfo() const { - return Pointer.get(); + return cast(Pointer); } - Expr *getAsExpr() const { return Pointer.get(); } + Expr *getAsExpr() const { return cast(Pointer); } NestedNameSpecifierLoc getTemplateQualifierLoc() const { const auto *Template = getTemplate(); diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h index 988b142a7672a..e54e7e527b8a3 100644 --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -411,6 +411,10 @@ class TextNodeDumper void VisitOpenACCConstructStmt(const OpenACCConstructStmt *S); void VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S); void VisitOpenACCCombinedConstruct(const OpenACCCombinedConstruct *S); + void VisitOpenACCDataConstruct(const OpenACCDataConstruct *S); + void VisitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct *S); + void VisitOpenACCExitDataConstruct(const OpenACCExitDataConstruct *S); + void VisitOpenACCHostDataConstruct(const OpenACCHostDataConstruct *S); void VisitOpenACCAsteriskSizeExpr(const OpenACCAsteriskSizeExpr *S); void VisitEmbedExpr(const EmbedExpr *S); void VisitAtomicExpr(const AtomicExpr *AE); diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 6fd6c73a516f0..09c98f642852f 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -934,11 +934,11 @@ class QualType { Qualifiers::FastWidth> Value; const ExtQuals *getExtQualsUnsafe() const { - return Value.getPointer().get(); + return cast(Value.getPointer()); } const Type *getTypePtrUnsafe() const { - return Value.getPointer().get(); + return cast(Value.getPointer()); } const ExtQualsTypeCommonBase *getCommonPtr() const { @@ -1064,7 +1064,7 @@ class QualType { /// "non-fast" qualifiers, e.g., those that are stored in an ExtQualType /// instance. bool hasLocalNonFastQualifiers() const { - return Value.getPointer().is(); + return isa(Value.getPointer()); } /// Retrieve the set of qualifiers local to this particular QualType @@ -6553,7 +6553,7 @@ class DeducedType : public Type { /// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained /// by a type-constraint. -class AutoType : public DeducedType, public llvm::FoldingSetNode { +class AutoType : public DeducedType { friend class ASTContext; // ASTContext creates these ConceptDecl *TypeConstraintConcept; diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 17fc36fbe2ac8..90d2a2056fe1b 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -4651,6 +4651,13 @@ def HLSLNumThreads: InheritableAttr { let Documentation = [NumThreadsDocs]; } +def HLSLSV_GroupThreadID: HLSLAnnotationAttr { + let Spellings = [HLSLAnnotation<"SV_GroupThreadID">]; + let Subjects = SubjectList<[ParmVar, Field]>; + let LangOpts = [HLSL]; + let Documentation = [HLSLSV_GroupThreadIDDocs]; +} + def HLSLSV_GroupID: HLSLAnnotationAttr { let Spellings = [HLSLAnnotation<"SV_GroupID">]; let Subjects = SubjectList<[ParmVar, Field]>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 7a82b8fa32059..fdad4c9a3ea19 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -7941,6 +7941,17 @@ randomized. }]; } +def HLSLSV_GroupThreadIDDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``SV_GroupThreadID`` semantic, when applied to an input parameter, specifies which +individual thread within a thread group is executing in. This attribute is +only supported in compute shaders. + +The full documentation is available here: https://docs.microsoft.com/en-us/windows/win32/direct3dhlsl/sv-groupthreadid + }]; +} + def HLSLSV_GroupIDDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h index 89f65682ae5b4..e27d8ccce7366 100644 --- a/clang/include/clang/Basic/Builtins.h +++ b/clang/include/clang/Basic/Builtins.h @@ -103,9 +103,7 @@ class Context { llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; } /// Get the type descriptor string for the specified builtin. - const char *getTypeString(unsigned ID) const { - return getRecord(ID).Type; - } + const char *getTypeString(unsigned ID) const { return getRecord(ID).Type; } /// Return true if this function is a target-specific builtin. bool isTSBuiltin(unsigned ID) const { diff --git a/clang/include/clang/Basic/Builtins.td b/clang/include/clang/Basic/Builtins.td index e2c3d3c535571..d64a66fc9d9cf 100644 --- a/clang/include/clang/Basic/Builtins.td +++ b/clang/include/clang/Basic/Builtins.td @@ -1450,13 +1450,13 @@ def ElementwiseFma : Builtin { def ElementwiseAddSat : Builtin { let Spellings = ["__builtin_elementwise_add_sat"]; - let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; let Prototype = "void(...)"; } def ElementwiseSubSat : Builtin { let Spellings = ["__builtin_elementwise_sub_sat"]; - let Attributes = [NoThrow, Const, CustomTypeChecking]; + let Attributes = [NoThrow, Const, CustomTypeChecking, Constexpr]; let Prototype = "void(...)"; } @@ -4762,6 +4762,12 @@ def HLSLAsDouble : LangBuiltin<"HLSL_LANG"> { let Prototype = "void(...)"; } +def HLSLWaveActiveAllTrue : LangBuiltin<"HLSL_LANG"> { + let Spellings = ["__builtin_hlsl_wave_active_all_true"]; + let Attributes = [NoThrow, Const]; + let Prototype = "bool(bool)"; +} + def HLSLWaveActiveAnyTrue : LangBuiltin<"HLSL_LANG"> { let Spellings = ["__builtin_hlsl_wave_active_any_true"]; let Attributes = [NoThrow, Const]; diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index d271accca3d3b..510b782e35d06 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -560,7 +560,8 @@ class DiagnosticsEngine : public RefCountedBase { ArgToStringFnTy ArgToStringFn; /// Whether the diagnostic should be suppressed in FilePath. - llvm::unique_function + llvm::unique_function DiagSuppressionMapping; public: @@ -972,7 +973,7 @@ class DiagnosticsEngine : public RefCountedBase { /// These take presumed locations into account, and can still be overriden by /// clang-diagnostics pragmas. void setDiagSuppressionMapping(llvm::MemoryBuffer &Input); - bool isSuppressedViaMapping(diag::kind DiagId, StringRef FilePath) const; + bool isSuppressedViaMapping(diag::kind DiagId, SourceLocation DiagLoc) const; /// Issue the message to the client. /// diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.td b/clang/include/clang/Basic/DiagnosticParseKinds.td index 9fa8d5901bd0a..86fcae209c40d 100644 --- a/clang/include/clang/Basic/DiagnosticParseKinds.td +++ b/clang/include/clang/Basic/DiagnosticParseKinds.td @@ -721,6 +721,9 @@ def warn_empty_init_statement : Warning< "has no effect">, InGroup, DefaultIgnore; def err_keyword_as_parameter : Error < "invalid parameter name: '%0' is a keyword">; +def warn_pre_cxx26_ambiguous_pack_indexing_type : Warning< + "%0 is no longer a pack expansion but a pack " + "indexing type; add a name to specify a pack expansion">, InGroup; // C++ derived classes def err_dup_virtual : Error<"duplicate 'virtual' in base specifier">; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 2137cb713164a..9344b620779b8 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3233,8 +3233,8 @@ def err_attribute_too_few_arguments : Error< "%0 attribute takes at least %1 argument%s1">; def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">; def err_attribute_invalid_bitint_vector_type : Error< - "'_BitInt' vector element width must be %select{a power of 2|" - "at least as wide as 'CHAR_BIT'}0">; + "'_BitInt' %select{vector|matrix}0 element width must be %select{a power of 2|" + "at least as wide as 'CHAR_BIT'}1">; def err_attribute_invalid_matrix_type : Error<"invalid matrix element type %0">; def err_attribute_bad_neon_vector_size : Error< "Neon vector size must be 64 or 128 bits">; @@ -10237,10 +10237,10 @@ def warn_dangling_pointer_assignment : Warning< InGroup; def warn_dangling_reference_captured : Warning< "object whose reference is captured by '%0' will be destroyed at the end of " - "the full-expression">, InGroup, DefaultIgnore; + "the full-expression">, InGroup; def warn_dangling_reference_captured_by_unknown : Warning< "object whose reference is captured will be destroyed at the end of " - "the full-expression">, InGroup, DefaultIgnore; + "the full-expression">, InGroup; // For non-floating point, expressions of the form x == x or x != x // should result in a warning, since these always evaluate to a constant. @@ -10274,6 +10274,11 @@ def warn_array_comparison : Warning< "to compare array addresses, use unary '+' to decay operands to pointers">, InGroup>; +def warn_array_comparison_cxx26 : Warning< + "comparison between two arrays is ill-formed in C++26; " + "to compare array addresses, use unary '+' to decay operands to pointers">, + InGroup>, DefaultError; + def warn_stringcompare : Warning< "result of comparison against %select{a string literal|@encode}0 is " "unspecified (use an explicit string comparison function instead)">, @@ -12677,6 +12682,9 @@ def err_acc_not_a_var_ref : Error<"OpenACC variable is not a valid variable name, sub-array, array " "element,%select{| member of a composite variable,}0 or composite " "variable member">; +def err_acc_not_a_var_ref_use_device + : Error<"OpenACC variable in 'use_device' clause is not a valid variable " + "name or array name">; def err_acc_typecheck_subarray_value : Error<"OpenACC sub-array subscripted value is not an array or pointer">; def err_acc_subarray_function_type @@ -12711,9 +12719,9 @@ def err_acc_clause_cannot_combine : Error<"OpenACC clause '%0' may not appear on the same construct as a " "'%1' clause on a '%2' construct">; def err_acc_reduction_num_gangs_conflict - : Error< - "OpenACC 'reduction' clause may not appear on a 'parallel' construct " - "with a 'num_gangs' clause with more than 1 argument, have %0">; + : Error<"OpenACC '%1' clause %select{|with more than 1 argument }0may not " + "appear on a '%2' construct " + "with a '%3' clause%select{ with more than 1 argument|}0">; def err_acc_reduction_type : Error<"OpenACC 'reduction' variable must be of scalar type, sub-array, or a " "composite of scalar types;%select{| sub-array base}1 type is %0">; @@ -12755,31 +12763,33 @@ def err_acc_gang_multiple_elt : Error<"OpenACC 'gang' clause may have at most one %select{unnamed or " "'num'|'dim'|'static'}0 argument">; def err_acc_int_arg_invalid - : Error<"'%1' argument on '%0' clause is not permitted on a%select{n " - "orphaned|||}2 'loop' construct %select{|associated with a " - "'parallel' compute construct|associated with a 'kernels' compute " - "construct|associated with a 'serial' compute construct}2">; + : Error<"'%0' argument on '%1' clause is not permitted on a%select{|n " + "orphaned}2 '%3' construct%select{| associated with a '%5' compute " + "construct}4">; def err_acc_gang_dim_value : Error<"argument to 'gang' clause dimension must be %select{a constant " "expression|1, 2, or 3: evaluated to %1}0">; def err_acc_num_arg_conflict - : Error<"'num' argument to '%0' clause not allowed on a 'loop' construct " - "associated with a 'kernels' construct that has a " - "'%select{num_gangs|num_workers|vector_length}1' " - "clause">; + : Error<"'%0' argument to '%1' clause not allowed on a '%2' " + "construct%select{| associated with a '%4' construct}3 that has a " + "'%5' clause">; +def err_acc_num_arg_conflict_reverse + : Error<"'%0' clause not allowed on a 'kernels loop' construct that " + "has a '%1' clause with a%select{n| 'num'}2 argument">; def err_acc_clause_in_clause_region : Error<"loop with a '%0' clause may not exist in the region of a '%1' " - "clause%select{| on a 'kernels' compute construct}2">; + "clause%select{| on a '%3' construct}2">; def err_acc_gang_reduction_conflict : Error<"%select{OpenACC 'gang' clause with a 'dim' value greater than " "1|OpenACC 'reduction' clause}0 cannot " - "appear on the same 'loop' construct as a %select{'reduction' " + "appear on the same '%1' construct as a %select{'reduction' " "clause|'gang' clause with a 'dim' value greater than 1}0">; def err_acc_gang_reduction_numgangs_conflict - : Error<"OpenACC '%0' clause cannot appear on the same 'loop' construct " - "as a '%1' clause inside a compute construct with a " + : Error<"OpenACC '%0' clause cannot appear on the same '%2' construct as a " + "'%1' clause %select{inside a compute construct with a|and a}3 " "'num_gangs' clause with more than one argument">; -def err_reduction_op_mismatch + + def err_reduction_op_mismatch : Error<"OpenACC 'reduction' variable must have the same operator in all " "nested constructs (%0 vs %1)">; def err_acc_loop_variable_type @@ -12794,6 +12804,8 @@ def err_acc_loop_terminating_condition def err_acc_loop_not_monotonic : Error<"OpenACC '%0' variable must monotonically increase or decrease " "('++', '--', or compound assignment)">; +def err_acc_construct_one_clause_of + : Error<"OpenACC '%0' construct must have at least one %1 clause">; // AMDGCN builtins diagnostics def err_amdgcn_global_load_lds_size_invalid_value : Error<"invalid size value">; diff --git a/clang/include/clang/Basic/FileEntry.h b/clang/include/clang/Basic/FileEntry.h index 68d4bf6093003..da5ba90974293 100644 --- a/clang/include/clang/Basic/FileEntry.h +++ b/clang/include/clang/Basic/FileEntry.h @@ -68,8 +68,13 @@ class FileEntryRef { StringRef getNameAsRequested() const { return ME->first(); } const FileEntry &getFileEntry() const { - return *getBaseMapEntry().second->V.get(); + return *cast(getBaseMapEntry().second->V); } + + // This function is used if the buffer size needs to be increased + // due to potential z/OS EBCDIC -> UTF-8 conversion + inline void updateFileEntryBufferSize(unsigned BufferSize); + DirectoryEntryRef getDir() const { return ME->second->Dir; } inline off_t getSize() const; @@ -323,6 +328,8 @@ class FileEntry { StringRef tryGetRealPathName() const { return RealPathName; } off_t getSize() const { return Size; } + // Size may increase due to potential z/OS EBCDIC -> UTF-8 conversion. + void setSize(off_t NewSize) { Size = NewSize; } unsigned getUID() const { return UID; } const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; } time_t getModificationTime() const { return ModTime; } @@ -353,6 +360,10 @@ bool FileEntryRef::isNamedPipe() const { return getFileEntry().isNamedPipe(); } void FileEntryRef::closeFile() const { getFileEntry().closeFile(); } +void FileEntryRef::updateFileEntryBufferSize(unsigned BufferSize) { + cast(getBaseMapEntry().second->V)->setSize(BufferSize); +} + } // end namespace clang #endif // LLVM_CLANG_BASIC_FILEENTRY_H diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index ae9ebd9f59154..33d1cdb46f108 100644 --- a/clang/include/clang/Basic/IdentifierTable.h +++ b/clang/include/clang/Basic/IdentifierTable.h @@ -1012,7 +1012,7 @@ class Selector { } MultiKeywordSelector *getMultiKeywordSelector() const { - return InfoPtr.getPointer().get(); + return cast(InfoPtr.getPointer()); } unsigned getIdentifierInfoFlag() const { @@ -1020,7 +1020,7 @@ class Selector { // IMPORTANT NOTE: We have to reconstitute this data rather than use the // value directly from the PointerIntPair. See the comments in `InfoPtr` // for more details. - if (InfoPtr.getPointer().is()) + if (isa(InfoPtr.getPointer())) new_flags |= MultiArg; return new_flags; } diff --git a/clang/include/clang/Basic/OpenACCClauses.def b/clang/include/clang/Basic/OpenACCClauses.def index c65ebed751cf1..c7ffac391e202 100644 --- a/clang/include/clang/Basic/OpenACCClauses.def +++ b/clang/include/clang/Basic/OpenACCClauses.def @@ -38,12 +38,16 @@ VISIT_CLAUSE(Create) CLAUSE_ALIAS(PCreate, Create, true) CLAUSE_ALIAS(PresentOrCreate, Create, true) VISIT_CLAUSE(Default) +VISIT_CLAUSE(Delete) +VISIT_CLAUSE(Detach) VISIT_CLAUSE(DevicePtr) VISIT_CLAUSE(DeviceType) CLAUSE_ALIAS(DType, DeviceType, false) +VISIT_CLAUSE(Finalize) VISIT_CLAUSE(FirstPrivate) VISIT_CLAUSE(Gang) VISIT_CLAUSE(If) +VISIT_CLAUSE(IfPresent) VISIT_CLAUSE(Independent) VISIT_CLAUSE(NoCreate) VISIT_CLAUSE(NumGangs) @@ -54,6 +58,7 @@ VISIT_CLAUSE(Reduction) VISIT_CLAUSE(Self) VISIT_CLAUSE(Seq) VISIT_CLAUSE(Tile) +VISIT_CLAUSE(UseDevice) VISIT_CLAUSE(Vector) VISIT_CLAUSE(VectorLength) VISIT_CLAUSE(Wait) diff --git a/clang/include/clang/Basic/OpenACCKinds.h b/clang/include/clang/Basic/OpenACCKinds.h index ea0bf23468cb8..7fb76271826a6 100644 --- a/clang/include/clang/Basic/OpenACCKinds.h +++ b/clang/include/clang/Basic/OpenACCKinds.h @@ -158,6 +158,14 @@ inline bool isOpenACCCombinedDirectiveKind(OpenACCDirectiveKind K) { K == OpenACCDirectiveKind::KernelsLoop; } +// Tests 'K' to see if it is 'data', 'host_data', 'enter data', or 'exit data'. +inline bool isOpenACCDataDirectiveKind(OpenACCDirectiveKind K) { + return K == OpenACCDirectiveKind::Data || + K == OpenACCDirectiveKind::EnterData || + K == OpenACCDirectiveKind::ExitData || + K == OpenACCDirectiveKind::HostData; +} + enum class OpenACCAtomicKind : uint8_t { Read, Write, diff --git a/clang/include/clang/Basic/StmtNodes.td b/clang/include/clang/Basic/StmtNodes.td index 89f5a76eb1131..0c3c580c218fd 100644 --- a/clang/include/clang/Basic/StmtNodes.td +++ b/clang/include/clang/Basic/StmtNodes.td @@ -308,6 +308,10 @@ def OpenACCAssociatedStmtConstruct def OpenACCComputeConstruct : StmtNode; def OpenACCLoopConstruct : StmtNode; def OpenACCCombinedConstruct : StmtNode; +def OpenACCDataConstruct : StmtNode; +def OpenACCEnterDataConstruct : StmtNode; +def OpenACCExitDataConstruct : StmtNode; +def OpenACCHostDataConstruct : StmtNode; // OpenACC Additional Expressions. def OpenACCAsteriskSizeExpr : StmtNode; diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index 4420228793e95..82bd537b242c1 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -1009,7 +1009,6 @@ class TargetInfo : public TransferrableTargetInfo, virtual void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const = 0; - /// Return information about target-specific builtins for /// the current primary target, and info about which builtins are non-portable /// across the current set of primary and secondary targets. diff --git a/clang/include/clang/Basic/arm_mve.td b/clang/include/clang/Basic/arm_mve.td index 93abbc47c54dd..6dd8c52ddfd77 100644 --- a/clang/include/clang/Basic/arm_mve.td +++ b/clang/include/clang/Basic/arm_mve.td @@ -1270,13 +1270,13 @@ defm sqrshr: ScalarSaturatingShiftReg; def lsll: LongScalarShift $lo, $hi, $sh)>; def asrl: LongScalarShift $lo, $hi, $sh)>; -multiclass vadcsbc { +multiclass vadcsbc { def q: Intrinsic:$carry), (seq (IRInt $a, $b, (shl (load $carry), 29)):$pair, (store (and 1, (lshr (xval $pair, 1), 29)), $carry), (xval $pair, 0))>; def iq: Intrinsic:$carry), - (seq (IRInt $a, $b, 0):$pair, + (seq (IRInt $a, $b, initial_carry_in):$pair, (store (and 1, (lshr (xval $pair, 1), 29)), $carry), (xval $pair, 0))>; def q_m: Intrinsic:$carry, Predicate:$pred), (seq (IRInt $inactive, $a, $b, - 0, $pred):$pair, + initial_carry_in, $pred):$pair, (store (and 1, (lshr (xval $pair, 1), 29)), $carry), (xval $pair, 0))>; } let params = T.Int32 in { - defm vadc: vadcsbc; - defm vsbc: vadcsbc; + defm vadc: vadcsbc<(u32 0)>; + defm vsbc: vadcsbc<(shl 1, 29)>; } let params = T.Int in { diff --git a/clang/include/clang/Basic/arm_sme.td b/clang/include/clang/Basic/arm_sme.td index 0f689e82bdb74..372cc1103d179 100644 --- a/clang/include/clang/Basic/arm_sme.td +++ b/clang/include/clang/Basic/arm_sme.td @@ -740,6 +740,38 @@ let SMETargetGuard = "sme2" in { def SVLUTI4_LANE_ZT_X2 : Inst<"svluti4_lane_zt_{d}_x2", "2.di[i", "cUcsUsiUibhf", MergeNone, "aarch64_sme_luti4_lane_zt_x2", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>, ImmCheck<2, ImmCheck0_3>]>; } +// +// SME2 FP8 instructions +// + +// FDOT +let SMETargetGuard = "sme-f8f32" in { + def SVDOT_LANE_FP8_ZA32_VG1x2 : Inst<"svdot_lane_za32[_mf8]_vg1x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za32_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_3>]>; + def SVDOT_LANE_FP8_ZA32_VG1x4 : Inst<"svdot_lane_za32[_mf8]_vg1x4_fpm", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za32_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_3>]>; + + def SVVDOTB_LANE_FP8_ZA32_VG1x4 : Inst<"svvdotb_lane_za32[_mf8]_vg1x4_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fvdotb_lane_za32_vg1x4", [IsOverloadNone, IsStreaming, IsInOutZA, SetsFPMR], [ImmCheck<3, ImmCheck0_3>]>; + def SVVDOTT_LANE_FP8_ZA32_VG1x4 : Inst<"svvdott_lane_za32[_mf8]_vg1x4_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fvdott_lane_za32_vg1x4", [IsOverloadNone, IsStreaming, IsInOutZA, SetsFPMR], [ImmCheck<3, ImmCheck0_3>]>; + + def SVDOT_SINGLE_FP8_ZA32_VG1x2 : Inst<"svdot[_single]_za32[_mf8]_vg1x2_fpm", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za32_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + def SVDOT_SINGLE_FP8_ZA32_VG1x4 : Inst<"svdot[_single]_za32[_mf8]_vg1x4_fpm", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za32_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + + def SVDOT_MULTI_FP8_ZA32_VG1x2 : Inst<"svdot_za32[_mf8]_vg1x2_fpm", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za32_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + def SVDOT_MULTI_FP8_ZA32_VG1x4 : Inst<"svdot_za32[_mf8]_vg1x4_fpm", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za32_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; +} + +let SMETargetGuard = "sme-f8f16" in { + def SVDOT_LANE_FP8_ZA16_VG1x2 : Inst<"svdot_lane_za16[_mf8]_vg1x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za16_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>; + def SVDOT_LANE_FP8_ZA16_VG1x4 : Inst<"svdot_lane_za16[_mf8]_vg1x4_fpm", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fdot_lane_za16_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_7>]>; + + def SVVDOT_LANE_FP8_ZA16_VG1x2 : Inst<"svvdot_lane_za16[_mf8]_vg1x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fvdot_lane_za16_vg1x2", [IsOverloadNone, IsStreaming, IsInOutZA, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>; + + def SVDOT_SINGLE_FP8_ZA16_VG1x2 : Inst<"svdot[_single]_za16[_mf8]_vg1x2_fpm", "vm2d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za16_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + def SVDOT_SINGLE_FP8_ZA16_VG1x4 : Inst<"svdot[_single]_za16[_mf8]_vg1x4_fpm", "vm4d>", "m", MergeNone, "aarch64_sme_fp8_fdot_single_za16_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + + def SVDOT_MULTI_FP8_ZA16_VG1x2 : Inst<"svdot_za16[_mf8]_vg1x2_fpm", "vm22>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za16_vg1x2", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; + def SVDOT_MULTI_FP8_ZA16_VG1x4 : Inst<"svdot_za16[_mf8]_vg1x4_fpm", "vm44>", "m", MergeNone, "aarch64_sme_fp8_fdot_multi_za16_vg1x4", [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], []>; +} + //////////////////////////////////////////////////////////////////////////////// // SME2p1 - FMOPA, FMOPS (non-widening) let SMETargetGuard = "sme-b16b16" in { @@ -824,4 +856,28 @@ let SMETargetGuard = "sme-lutv2" in { def SVLUTI4_ZT_X4 : SInst<"svluti4_zt_{d}_x4", "4i2.u", "cUc", MergeNone, "aarch64_sme_luti4_zt_x4", [IsStreaming, IsInZT0], [ImmCheck<0, ImmCheck0_0>]>; } +let SMETargetGuard = "sme-f8f32" in { + def SVMOPA_FP8_ZA32 : Inst<"svmopa_za32[_mf8]_m_fpm", "viPPdd>", "m", MergeNone, "aarch64_sme_fp8_fmopa_za32", + [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<0, ImmCheck0_3>]>; + // FMLALL (indexed) + def SVMLA_FP8_ZA32_VG4x1 : Inst<"svmla_lane_za32[_mf8]_vg4x1_fpm", "vmddi>", "m", MergeNone, "aarch64_sme_fp8_fmlall_lane_za32_vg4x1", + [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLA_FP8_ZA32_VG4x2 : Inst<"svmla_lane_za32[_mf8]_vg4x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fmlall_lane_za32_vg4x2", + [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLA_FP8_ZA16_VG4x4 : Inst<"svmla_lane_za32[_mf8]_vg4x4_fpm", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fmlall_lane_za32_vg4x4", + [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; +} + +let SMETargetGuard = "sme-f8f16" in { + def SVMOPA_FP8_ZA16 : Inst<"svmopa_za16[_mf8]_m_fpm", "viPPdd>", "m", MergeNone, "aarch64_sme_fp8_fmopa_za16", + [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<0, ImmCheck0_1>]>; + // FMLAL (indexed) + def SVMLA_FP8_ZA16_VG2x1 : Inst<"svmla_lane_za16[_mf8]_vg2x1_fpm", "vmddi>", "m", MergeNone, "aarch64_sme_fp8_fmlal_lane_za16_vg2x1", + [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLA_FP8_ZA16_VG2x2 : Inst<"svmla_lane_za16[_mf8]_vg2x2_fpm", "vm2di>", "m", MergeNone, "aarch64_sme_fp8_fmlal_lane_za16_vg2x2", + [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; + def SVMLA_FP8_ZA16_VG2x4 : Inst<"svmla_lane_za16[_mf8]_vg2x4_fpm", "vm4di>", "m", MergeNone, "aarch64_sme_fp8_fmlal_lane_za16_vg2x4", + [IsStreaming, IsInOutZA, SetsFPMR, IsOverloadNone], [ImmCheck<3, ImmCheck0_15>]>; +} + } // let SVETargetGuard = InvalidMode diff --git a/clang/include/clang/Basic/arm_sve.td b/clang/include/clang/Basic/arm_sve.td index e551d6e46b8f3..e9396e34adad8 100644 --- a/clang/include/clang/Basic/arm_sve.td +++ b/clang/include/clang/Basic/arm_sve.td @@ -2429,9 +2429,19 @@ let SVETargetGuard = InvalidMode, SMETargetGuard = "sme2,fp8" in { def FSCALE_X2 : Inst<"svscale[_{d}_x2]", "222.x", "fhd", MergeNone, "aarch64_sme_fp8_scale_x2", [IsStreaming],[]>; def FSCALE_X4 : Inst<"svscale[_{d}_x4]", "444.x", "fhd", MergeNone, "aarch64_sme_fp8_scale_x4", [IsStreaming],[]>; + // Convert from FP8 to half-precision/BFloat16 multi-vector + def SVF1CVT_X2 : Inst<"svcvt1_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvt1_x2", [IsStreaming, SetsFPMR], []>; + def SVF2CVT_X2 : Inst<"svcvt2_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvt2_x2", [IsStreaming, SetsFPMR], []>; + // Convert from FP8 to deinterleaved half-precision/BFloat16 multi-vector - def SVF1CVTL : Inst<"svcvtl1_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvtl1_x2", [IsStreaming, SetsFPMR], []>; - def SVF2CVTL : Inst<"svcvtl2_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvtl2_x2", [IsStreaming, SetsFPMR], []>; + def SVF1CVTL_X2 : Inst<"svcvtl1_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvtl1_x2", [IsStreaming, SetsFPMR], []>; + def SVF2CVTL_X2 : Inst<"svcvtl2_{d}[_mf8]_x2_fpm", "2~>", "bh", MergeNone, "aarch64_sve_fp8_cvtl2_x2", [IsStreaming, SetsFPMR], []>; + + // Convert from single/half/bfloat multivector to FP8 + def SVFCVT_X2 : Inst<"svcvt_mf8[_{d}_x2]_fpm", "~2>", "bh", MergeNone, "aarch64_sve_fp8_cvt_x2", [IsStreaming, SetsFPMR], []>; + def SVFCVT_X4 : Inst<"svcvt_mf8[_{d}_x4]_fpm", "~4>", "f", MergeNone, "aarch64_sve_fp8_cvt_x4", [IsOverloadNone, IsStreaming, SetsFPMR], []>; + // interleaved + def SVFCVTN_X4 : Inst<"svcvtn_mf8[_{d}_x4]_fpm", "~4>", "f", MergeNone, "aarch64_sve_fp8_cvtn_x4", [IsOverloadNone, IsStreaming, SetsFPMR], []>; } let SVETargetGuard = "sve2p1", SMETargetGuard = "sme2" in { @@ -2447,3 +2457,72 @@ let SVETargetGuard = "sve2,faminmax", SMETargetGuard = "sme2,faminmax" in { defm SVAMIN : SInstZPZZ<"svamin", "hfd", "aarch64_sve_famin", "aarch64_sve_famin_u">; defm SVAMAX : SInstZPZZ<"svamax", "hfd", "aarch64_sve_famax", "aarch64_sve_famax_u">; } + +let SVETargetGuard = "sve2,fp8", SMETargetGuard = "sme2,fp8" in { + // SVE FP8 widening conversions + + // 8-bit floating-point convert to BFloat16/Float16 + def SVF1CVT : SInst<"svcvt1_{d}[_mf8]_fpm", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvt1", [VerifyRuntimeMode, SetsFPMR]>; + def SVF2CVT : SInst<"svcvt2_{d}[_mf8]_fpm", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvt2", [VerifyRuntimeMode, SetsFPMR]>; + + // 8-bit floating-point convert to BFloat16/Float16 (top) + def SVF1CVTLT : SInst<"svcvtlt1_{d}[_mf8]_fpm", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvtlt1", [VerifyRuntimeMode, SetsFPMR]>; + def SVF2CVTLT : SInst<"svcvtlt2_{d}[_mf8]_fpm", "d~>", "bh", MergeNone, "aarch64_sve_fp8_cvtlt2", [VerifyRuntimeMode, SetsFPMR]>; + + // BFloat16/Float16 convert, narrow and interleave to 8-bit floating-point + def SVFCVTN : SInst<"svcvtn_mf8[_{d}_x2]_fpm", "~2>", "bh", MergeNone, "aarch64_sve_fp8_cvtn", [VerifyRuntimeMode, SetsFPMR]>; + + // Single-precision convert, narrow and interleave to 8-bit floating-point (top and bottom) + def SVFCVTNB : SInst<"svcvtnb_mf8[_f32_x2]_fpm", "~2>", "f", MergeNone, "aarch64_sve_fp8_cvtnb", [VerifyRuntimeMode, SetsFPMR]>; + def SVFCVTNT : SInst<"svcvtnt_mf8[_f32_x2]_fpm", "~~2>", "f", MergeNone, "aarch64_sve_fp8_cvtnt", [VerifyRuntimeMode, SetsFPMR]>; +} + +let SVETargetGuard = "sve2,fp8dot2", SMETargetGuard ="sme,ssve-fp8dot2" in { + // 8-bit floating-point dot product to half-precision (vectors) + def SVFDOT_2WAY : SInst<"svdot[_f16_mf8]_fpm", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode, SetsFPMR]>; + def SVFDOT_N_2WAY : SInst<"svdot[_n_f16_mf8]_fpm", "dd~!>", "h", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode, SetsFPMR]>; + + // 8-bit floating-point dot product to half-precision (indexed) + def SVFDOT_LANE_2WAY : SInst<"svdot_lane[_f16_mf8]_fpm", "dd~~i>", "h", MergeNone, "aarch64_sve_fp8_fdot_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>; +} + +let SVETargetGuard = "sve2,fp8dot4", SMETargetGuard ="sme,ssve-fp8dot4" in { + // 8-bit floating-point dot product to single-precision (vectors) + def SVFDOT_4WAY : SInst<"svdot[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode, SetsFPMR]>; + def SVFDOT_N_4WAY : SInst<"svdot[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fdot", [VerifyRuntimeMode, SetsFPMR]>; + + // 8-bit floating-point dot product to single-precision (indexed) + def SVFDOT_LANE_4WAY : SInst<"svdot_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fdot_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_3>]>; +} + +let SVETargetGuard = "sve2,fp8fma", SMETargetGuard = "sme,ssve-fp8fma" in { + // 8-bit floating-point multiply-add long to half-precision (bottom) + def SVFMLALB : SInst<"svmlalb[_f16_mf8]_fpm", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fmlalb", [VerifyRuntimeMode, SetsFPMR]>; + def SVFMLALB_N : SInst<"svmlalb[_n_f16_mf8]_fpm", "dd~!>", "h", MergeNone, "aarch64_sve_fp8_fmlalb", [VerifyRuntimeMode, SetsFPMR]>; + + // 8-bit floating-point multiply-add long to ha_fpmlf-precision (bottom, indexed) + def SVFMLALB_LANE : SInst<"svmlalb_lane[_f16_mf8]_fpm", "dd~~i>", "h", MergeNone, "aarch64_sve_fp8_fmlalb_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_15>]>; + + // 8-bit floating-point multiply-add long to half-precision (top) + def SVFMLALT : SInst<"svmlalt[_f16_mf8]_fpm", "dd~~>", "h", MergeNone, "aarch64_sve_fp8_fmlalt", [VerifyRuntimeMode, SetsFPMR]>; + def SVFMLALT_N : SInst<"svmlalt[_n_f16_mf8]_fpm", "dd~!>", "h", MergeNone, "aarch64_sve_fp8_fmlalt", [VerifyRuntimeMode, SetsFPMR]>; + + // 8-bit floating-point multiply-add long to half-precision (top, indexed) + def SVFMLALT_LANE : SInst<"svmlalt_lane[_f16_mf8]_fpm", "dd~~i>", "h", MergeNone, "aarch64_sve_fp8_fmlalt_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_15>]>; + + // 8-bit floating-point multiply-add long long to single-precision (all top/bottom variants) + def SVFMLALLBB : SInst<"svmlallbb[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlallbb", [VerifyRuntimeMode, SetsFPMR]>; + def SVFMLALLBB_N : SInst<"svmlallbb[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlallbb", [VerifyRuntimeMode, SetsFPMR]>; + def SVFMLALLBT : SInst<"svmlallbt[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlallbt", [VerifyRuntimeMode, SetsFPMR]>; + def SVFMLALLBT_N : SInst<"svmlallbt[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlallbt", [VerifyRuntimeMode, SetsFPMR]>; + def SVFMLALLTB : SInst<"svmlalltb[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb", [VerifyRuntimeMode, SetsFPMR]>; + def SVFMLALLTB_N : SInst<"svmlalltb[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb", [VerifyRuntimeMode, SetsFPMR]>; + def SVFMLALLTT : SInst<"svmlalltt[_f32_mf8]_fpm", "dd~~>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt", [VerifyRuntimeMode, SetsFPMR]>; + def SVFMLALLTT_N : SInst<"svmlalltt[_n_f32_mf8]_fpm", "dd~!>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt", [VerifyRuntimeMode, SetsFPMR]>; + + // 8-bit floating-point multiply-add long long to single-precision (indexed, all top/bottom variants) + def SVFMLALLBB_LANE : SInst<"svmlallbb_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlallbb_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>; + def SVFMLALLBT_LANE : SInst<"svmlallbt_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlallbt_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>; + def SVFMLALLTB_LANE : SInst<"svmlalltb_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlalltb_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>; + def SVFMLALLTT_LANE : SInst<"svmlalltt_lane[_f32_mf8]_fpm", "dd~~i>", "f", MergeNone, "aarch64_sve_fp8_fmlalltt_lane", [VerifyRuntimeMode, SetsFPMR], [ImmCheck<3, ImmCheck0_7>]>; +} diff --git a/clang/include/clang/Basic/arm_sve_sme_incl.td b/clang/include/clang/Basic/arm_sve_sme_incl.td index de10be7bdce0d..ee899209ad832 100644 --- a/clang/include/clang/Basic/arm_sve_sme_incl.td +++ b/clang/include/clang/Basic/arm_sve_sme_incl.td @@ -52,6 +52,7 @@ include "arm_immcheck_incl.td" // h: half-float // d: double // b: bfloat +// m: mfloat8 // Typespec modifiers // ------------------ @@ -88,6 +89,7 @@ include "arm_immcheck_incl.td" // j: element type promoted to 64bits (splat to vector type) // K: element type bitcast to a signed integer (splat to vector type) // L: element type bitcast to an unsigned integer (splat to vector type) +// !: mfloat8_t (splat to svmfloat8_t) // // i: constant uint64_t // k: int32_t diff --git a/clang/include/clang/CIR/CIRGenerator.h b/clang/include/clang/CIR/CIRGenerator.h index c8ca7e4bfa728..414eba80b88b8 100644 --- a/clang/include/clang/CIR/CIRGenerator.h +++ b/clang/include/clang/CIR/CIRGenerator.h @@ -37,14 +37,14 @@ namespace cir { class CIRGenerator : public clang::ASTConsumer { virtual void anchor(); clang::DiagnosticsEngine &diags; - clang::ASTContext *astCtx; + clang::ASTContext *astContext; // Only used for debug info. llvm::IntrusiveRefCntPtr fs; const clang::CodeGenOptions &codeGenOpts; protected: - std::unique_ptr mlirCtx; + std::unique_ptr mlirContext; std::unique_ptr cgm; public: @@ -52,7 +52,7 @@ class CIRGenerator : public clang::ASTConsumer { llvm::IntrusiveRefCntPtr fs, const clang::CodeGenOptions &cgo); ~CIRGenerator() override; - void Initialize(clang::ASTContext &astCtx) override; + void Initialize(clang::ASTContext &astContext) override; bool HandleTopLevelDecl(clang::DeclGroupRef group) override; mlir::ModuleOp getModule() const; }; diff --git a/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h new file mode 100644 index 0000000000000..75ae74e926fbc --- /dev/null +++ b/clang/include/clang/CIR/Dialect/Builder/CIRBaseBuilder.h @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H +#define LLVM_CLANG_CIR_DIALECT_BUILDER_CIRBASEBUILDER_H + +#include "mlir/IR/Builders.h" + +namespace cir { + +class CIRBaseBuilderTy : public mlir::OpBuilder { + +public: + CIRBaseBuilderTy(mlir::MLIRContext &mlirContext) + : mlir::OpBuilder(&mlirContext) {} +}; + +} // namespace cir + +#endif diff --git a/clang/include/clang/CIR/Dialect/IR/CIROps.td b/clang/include/clang/CIR/Dialect/IR/CIROps.td index 4462eb6fc00ba..0d6c65ecf4102 100644 --- a/clang/include/clang/CIR/Dialect/IR/CIROps.td +++ b/clang/include/clang/CIR/Dialect/IR/CIROps.td @@ -15,6 +15,7 @@ #define LLVM_CLANG_CIR_DIALECT_IR_CIROPS include "clang/CIR/Dialect/IR/CIRDialect.td" +include "clang/CIR/Dialect/IR/CIRTypes.td" include "mlir/IR/BuiltinAttributeInterfaces.td" include "mlir/IR/EnumAttr.td" @@ -74,6 +75,35 @@ class LLVMLoweringInfo { class CIR_Op traits = []> : Op, LLVMLoweringInfo; +//===----------------------------------------------------------------------===// +// GlobalOp +//===----------------------------------------------------------------------===// + +// 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 +// is upstreamed. + +def GlobalOp : CIR_Op<"global"> { + let summary = "Declare or define a global variable"; + let description = [{ + The `cir.global` operation declares or defines a named global variable. + + The backing memory for the variable is allocated statically and is + described by the type of the variable. + }]; + + let arguments = (ins SymbolNameAttr:$sym_name, TypeAttr:$sym_type); + + let assemblyFormat = [{ $sym_name `:` $sym_type attr-dict }]; + + let skipDefaultBuilders = 1; + + let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name, + "mlir::Type":$sym_type)>]; + + let hasVerifier = 1; +} + //===----------------------------------------------------------------------===// // FuncOp //===----------------------------------------------------------------------===// @@ -85,14 +115,15 @@ class CIR_Op traits = []> : def FuncOp : CIR_Op<"func"> { let summary = "Declare or define a function"; let description = [{ - ... lots of text to be added later ... + The `cir.func` operation defines a function, similar to the `mlir::FuncOp` + built-in. }]; let arguments = (ins SymbolNameAttr:$sym_name); let skipDefaultBuilders = 1; - let builders = [OpBuilder<(ins "llvm::StringRef":$name)>]; + let builders = [OpBuilder<(ins "llvm::StringRef":$sym_name)>]; let hasCustomAssemblyFormat = 1; let hasVerifier = 1; diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.h b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h new file mode 100644 index 0000000000000..2bc7d77b2bc8a --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.h @@ -0,0 +1,27 @@ +//===----------------------------------------------------------------------===// +// +// 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 declares the types in the CIR dialect. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_DIALECT_CIR_IR_CIRTYPES_H_ +#define MLIR_DIALECT_CIR_IR_CIRTYPES_H_ + +#include "mlir/IR/BuiltinAttributes.h" +#include "mlir/IR/Types.h" +#include "mlir/Interfaces/DataLayoutInterfaces.h" + +//===----------------------------------------------------------------------===// +// CIR Dialect Tablegen'd Types +//===----------------------------------------------------------------------===// + +#define GET_TYPEDEF_CLASSES +#include "clang/CIR/Dialect/IR/CIROpsTypes.h.inc" + +#endif // MLIR_DIALECT_CIR_IR_CIRTYPES_H_ diff --git a/clang/include/clang/CIR/Dialect/IR/CIRTypes.td b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td new file mode 100644 index 0000000000000..ce0b6ba1d68c5 --- /dev/null +++ b/clang/include/clang/CIR/Dialect/IR/CIRTypes.td @@ -0,0 +1,132 @@ +//===- CIRTypes.td - CIR dialect types ---------------------*- tablegen -*-===// +// +// 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 declares the CIR dialect types. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_CIR_DIALECT_CIR_TYPES +#define MLIR_CIR_DIALECT_CIR_TYPES + +include "clang/CIR/Dialect/IR/CIRDialect.td" +include "mlir/Interfaces/DataLayoutInterfaces.td" +include "mlir/IR/AttrTypeBase.td" + +//===----------------------------------------------------------------------===// +// CIR Types +//===----------------------------------------------------------------------===// + +class CIR_Type traits = [], + string baseCppClass = "::mlir::Type"> + : TypeDef { + let mnemonic = typeMnemonic; +} + +//===----------------------------------------------------------------------===// +// IntType +//===----------------------------------------------------------------------===// + +def CIR_IntType : CIR_Type<"Int", "int", + [DeclareTypeInterfaceMethods]> { + let summary = "Integer type with arbitrary precision up to a fixed limit"; + let description = [{ + CIR type that represents integer types with arbitrary precision, including + standard integral types such as `int` and `long`, extended integral types + such as `__int128`, and arbitrary width types such as `_BitInt(n)`. + + Those integer types that are directly available in C/C++ standard are called + primitive integer types. Said types are: `signed char`, `short`, `int`, + `long`, `long long`, and their unsigned variations. + }]; + let parameters = (ins "unsigned":$width, "bool":$isSigned); + let hasCustomAssemblyFormat = 1; + let extraClassDeclaration = [{ + /// Return true if this is a signed integer type. + bool isSigned() const { return getIsSigned(); } + /// Return true if this is an unsigned integer type. + bool isUnsigned() const { return !getIsSigned(); } + /// Return type alias. + std::string getAlias() const { + return (isSigned() ? 's' : 'u') + std::to_string(getWidth()) + 'i'; + } + /// Return true if this is a primitive integer type (i.e. signed or unsigned + /// integer types whose bit width is 8, 16, 32, or 64). + bool isPrimitive() const { + return isValidPrimitiveIntBitwidth(getWidth()); + } + bool isSignedPrimitive() const { + return isPrimitive() && isSigned(); + } + + /// Returns a minimum bitwidth of cir::IntType + static unsigned minBitwidth() { return 1; } + /// Returns a maximum bitwidth of cir::IntType + static unsigned maxBitwidth() { return 128; } + + /// Returns true if cir::IntType that represents a primitive integer type + /// can be constructed from the provided bitwidth. + static bool isValidPrimitiveIntBitwidth(unsigned width) { + return width == 8 || width == 16 || width == 32 || width == 64; + } + }]; + let genVerifyDecl = 1; +} + +// Constraints + +// Unsigned integer type of a specific width. +class UInt + : Type($_self)">, + CPred<"::mlir::cast<::cir::IntType>($_self).isUnsigned()">, + CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width> + ]>, width # "-bit unsigned integer", "::cir::IntType">, + BuildableType< + "cir::IntType::get($_builder.getContext(), " + # width # ", /*isSigned=*/false)"> { + int bitwidth = width; +} + +def UInt1 : UInt<1>; +def UInt8 : UInt<8>; +def UInt16 : UInt<16>; +def UInt32 : UInt<32>; +def UInt64 : UInt<64>; + +// Signed integer type of a specific width. +class SInt + : Type($_self)">, + CPred<"::mlir::cast<::cir::IntType>($_self).isSigned()">, + CPred<"::mlir::cast<::cir::IntType>($_self).getWidth() == " # width> + ]>, width # "-bit signed integer", "::cir::IntType">, + BuildableType< + "cir::IntType::get($_builder.getContext(), " + # width # ", /*isSigned=*/true)"> { + int bitwidth = width; +} + +def SInt1 : SInt<1>; +def SInt8 : SInt<8>; +def SInt16 : SInt<16>; +def SInt32 : SInt<32>; +def SInt64 : SInt<64>; + +def PrimitiveUInt + : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64], "primitive unsigned int", + "::cir::IntType">; + +def PrimitiveSInt + : AnyTypeOf<[SInt8, SInt16, SInt32, SInt64], "primitive signed int", + "::cir::IntType">; + +def PrimitiveInt + : AnyTypeOf<[UInt8, UInt16, UInt32, UInt64, SInt8, SInt16, SInt32, SInt64], + "primitive int", "::cir::IntType">; + +#endif // MLIR_CIR_DIALECT_CIR_TYPES diff --git a/clang/include/clang/Driver/Driver.h b/clang/include/clang/Driver/Driver.h index 9177d56718ee7..c23d037e725bb 100644 --- a/clang/include/clang/Driver/Driver.h +++ b/clang/include/clang/Driver/Driver.h @@ -297,8 +297,11 @@ class Driver { /// Object that stores strings read from configuration file. llvm::StringSaver Saver; - /// Arguments originated from configuration file. - std::unique_ptr CfgOptions; + /// Arguments originated from configuration file (head part). + std::unique_ptr CfgOptionsHead; + + /// Arguments originated from configuration file (tail part). + std::unique_ptr CfgOptionsTail; /// Arguments originated from command line. std::unique_ptr CLOptions; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 05b9068f336d3..15bdf9ebc556b 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -240,7 +240,8 @@ def m_riscv_Features_Group : OptionGroup<"">, def m_ve_Features_Group : OptionGroup<"">, Group, DocName<"VE">; def m_loongarch_Features_Group : OptionGroup<"">, - Group, DocName<"LoongArch">; + Group, DocName<"LoongArch">, + Visibility<[ClangOption, CLOption, FlangOption]>; def m_libc_Group : OptionGroup<"">, Group, Flags<[HelpHidden]>; @@ -1055,11 +1056,11 @@ def z : Separate<["-"], "z">, Flags<[LinkerInput]>, def offload_link : Flag<["--"], "offload-link">, Group, HelpText<"Use the new offloading linker to perform the link job.">; def Xlinker : Separate<["-"], "Xlinker">, Flags<[LinkerInput, RenderAsInput]>, - Visibility<[ClangOption, CLOption, FlangOption, DXCOption]>, + Visibility<[ClangOption, CLOption, FlangOption]>, HelpText<"Pass to the linker">, MetaVarName<"">, Group; def Xoffload_linker : JoinedAndSeparate<["-"], "Xoffload-linker">, - Visibility<[ClangOption, CLOption, FlangOption, DXCOption]>, + Visibility<[ClangOption, FlangOption]>, HelpText<"Pass to the offload linkers or the ones identified by -">, MetaVarName<" ">, Group; def Xpreprocessor : Separate<["-"], "Xpreprocessor">, Group, @@ -1175,7 +1176,7 @@ def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">; def config : Joined<["--"], "config=">, Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, MetaVarName<"">, HelpText<"Specify configuration file">; -def : Separate<["--"], "config">, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, Alias; +def : Separate<["--"], "config">, Visibility<[ClangOption, FlangOption]>, Alias; def no_default_config : Flag<["--"], "no-default-config">, Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, HelpText<"Disable loading default configuration files">; @@ -1989,7 +1990,7 @@ def : Flag<["-"], "fno-diagnostics-color">, Group, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, Alias; def fdiagnostics_color_EQ : Joined<["-"], "fdiagnostics-color=">, Group, - Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, + Visibility<[ClangOption, FlangOption]>, Values<"auto,always,never">, HelpText<"When to use colors in diagnostics">; def fansi_escape_codes : Flag<["-"], "fansi-escape-codes">, Group, @@ -2015,10 +2016,10 @@ argument are escaped with backslashes. This format differs from the format of the equivalent section produced by GCC with the -frecord-gcc-switches flag. This option is currently only supported on ELF targets.}]>, Group, - Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>; + Visibility<[ClangOption, FlangOption]>; def fno_record_command_line : Flag<["-"], "fno-record-command-line">, Group, - Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>; + Visibility<[ClangOption, FlangOption]>; def : Flag<["-"], "frecord-gcc-switches">, Alias; def : Flag<["-"], "fno-record-gcc-switches">, Alias; def fcommon : Flag<["-"], "fcommon">, Group, @@ -3194,11 +3195,14 @@ defm skip_odr_check_in_gmf : BoolOption<"f", "skip-odr-check-in-gmf", "Perform ODR checks for decls in the global module fragment.">>, Group; -def modules_reduced_bmi : Flag<["-"], "fexperimental-modules-reduced-bmi">, +def modules_reduced_bmi : Flag<["-"], "fmodules-reduced-bmi">, Group, Visibility<[ClangOption, CC1Option]>, HelpText<"Generate the reduced BMI">, MarshallingInfoFlag>; +def experimental_modules_reduced_bmi : Flag<["-"], "fexperimental-modules-reduced-bmi">, + Group, Visibility<[ClangOption, CC1Option]>, Alias; + def fmodules_embed_all_files : Joined<["-"], "fmodules-embed-all-files">, Visibility<[ClangOption, CC1Option, CLOption]>, HelpText<"Embed the contents of all files read by this compilation into " @@ -5644,7 +5648,7 @@ def gpulibc : Flag<["-"], "gpulibc">, Visibility<[ClangOption, CC1Option, FlangO HelpText<"Link the LLVM C Library for GPUs">; def nogpulibc : Flag<["-"], "nogpulibc">, Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>; def nodefaultlibs : Flag<["-"], "nodefaultlibs">, - Visibility<[ClangOption, FlangOption, CLOption, DXCOption]>; + Visibility<[ClangOption, FlangOption]>; def nodriverkitlib : Flag<["-"], "nodriverkitlib">; def nofixprebinding : Flag<["-"], "nofixprebinding">; def nolibc : Flag<["-"], "nolibc">; @@ -5666,10 +5670,10 @@ def nostdincxx : Flag<["-"], "nostdinc++">, Visibility<[ClangOption, CC1Option]> HelpText<"Disable standard #include directories for the C++ standard library">, MarshallingInfoNegativeFlag>; def nostdlib : Flag<["-"], "nostdlib">, - Visibility<[ClangOption, CLOption, FlangOption, DXCOption]>, + Visibility<[ClangOption, FlangOption]>, Group; def stdlib : Flag<["-"], "stdlib">, - Visibility<[ClangOption, CLOption, FlangOption, DXCOption]>, + Visibility<[ClangOption, FlangOption]>, Group; def nostdlibxx : Flag<["-"], "nostdlib++">; def object : Flag<["-"], "object">; @@ -5783,7 +5787,7 @@ def resource_dir_EQ : Joined<["-"], "resource-dir=">, Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, Alias; def rpath : Separate<["-"], "rpath">, Flags<[LinkerInput]>, Group, - Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>; + Visibility<[ClangOption, FlangOption]>; def rtlib_EQ : Joined<["-", "--"], "rtlib=">, Visibility<[ClangOption, CLOption, FlangOption]>, HelpText<"Compiler runtime library to use">; def frtlib_add_rpath: Flag<["-"], "frtlib-add-rpath">, Flags<[NoArgumentUnused]>, @@ -5847,7 +5851,7 @@ def segs__read__write__addr : Separate<["-"], "segs_read_write_addr">; def segs__read__ : Joined<["-"], "segs_read_">; def shared_libgcc : Flag<["-"], "shared-libgcc">; def shared : Flag<["-", "--"], "shared">, Group, - Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>; + Visibility<[ClangOption, FlangOption]>; def single__module : Flag<["-"], "single_module">; def specs_EQ : Joined<["-", "--"], "specs=">, Group; def specs : Separate<["-", "--"], "specs">, Flags<[Unsupported]>; @@ -5857,7 +5861,7 @@ def start_no_unused_arguments : Flag<["--"], "start-no-unused-arguments">, def static_libgcc : Flag<["-"], "static-libgcc">; def static_libstdcxx : Flag<["-"], "static-libstdc++">; def static : Flag<["-", "--"], "static">, Group, - Visibility<[ClangOption, CLOption, DXCOption, FlangOption]>, + Visibility<[ClangOption, FlangOption]>, Flags<[NoArgumentUnused]>; def std_default_EQ : Joined<["-"], "std-default=">; def std_EQ : Joined<["-", "--"], "std=">, @@ -6836,10 +6840,6 @@ def flang_deprecated_no_hlfir : Flag<["-"], "flang-deprecated-no-hlfir">, Flags<[HelpHidden]>, Visibility<[FlangOption, FC1Option]>, HelpText<"Do not use HLFIR lowering (deprecated)">; -def flang_experimental_integer_overflow : Flag<["-"], "flang-experimental-integer-overflow">, - Flags<[HelpHidden]>, Visibility<[FlangOption, FC1Option]>, - HelpText<"Add nsw flag to internal operations such as do-variable increment (experimental)">; - //===----------------------------------------------------------------------===// // FLangOption + CoreOption + NoXarchOption //===----------------------------------------------------------------------===// diff --git a/clang/include/clang/Lex/PreprocessingRecord.h b/clang/include/clang/Lex/PreprocessingRecord.h index 437d8e4cc174e..7886aef7f0c7f 100644 --- a/clang/include/clang/Lex/PreprocessingRecord.h +++ b/clang/include/clang/Lex/PreprocessingRecord.h @@ -180,13 +180,13 @@ class Token; } /// True if it is a builtin macro. - bool isBuiltinMacro() const { return NameOrDef.is(); } + bool isBuiltinMacro() const { return isa(NameOrDef); } /// The name of the macro being expanded. const IdentifierInfo *getName() const { if (MacroDefinitionRecord *Def = getDefinition()) return Def->getName(); - return NameOrDef.get(); + return cast(NameOrDef); } /// The definition of the macro being expanded. May return null if diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 3312d4ed1d798..3d223c345ea15 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -859,7 +859,7 @@ class Preprocessor { auto *Info = State.dyn_cast(); if (!Info) { Info = new (PP.getPreprocessorAllocator()) - ModuleMacroInfo(State.get()); + ModuleMacroInfo(cast(State)); State = Info; } @@ -892,7 +892,7 @@ class Preprocessor { MacroDirective *getLatest() const { if (auto *Info = State.dyn_cast()) return Info->MD; - return State.get(); + return cast(State); } void setLatest(MacroDirective *MD) { @@ -945,7 +945,7 @@ class Preprocessor { if (Overrides.empty()) return; Info = new (PP.getPreprocessorAllocator()) - ModuleMacroInfo(State.get()); + ModuleMacroInfo(cast(State)); State = Info; } Info->OverriddenMacros.clear(); diff --git a/clang/include/clang/Sema/MultiplexExternalSemaSource.h b/clang/include/clang/Sema/MultiplexExternalSemaSource.h index 3d1906d869926..0c92c52854c9e 100644 --- a/clang/include/clang/Sema/MultiplexExternalSemaSource.h +++ b/clang/include/clang/Sema/MultiplexExternalSemaSource.h @@ -97,6 +97,12 @@ class MultiplexExternalSemaSource : public ExternalSemaSource { bool FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) override; + bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override; + + bool + LoadExternalSpecializations(const Decl *D, + ArrayRef TemplateArgs) override; + /// Ensures that the table of all visible declarations inside this /// context is up to date. void completeVisibleDeclsMap(const DeclContext *DC) override; diff --git a/clang/include/clang/Sema/ParsedAttr.h b/clang/include/clang/Sema/ParsedAttr.h index 22cbd0d90ee43..4fa5fbdb5a7f6 100644 --- a/clang/include/clang/Sema/ParsedAttr.h +++ b/clang/include/clang/Sema/ParsedAttr.h @@ -392,19 +392,17 @@ class ParsedAttr final } bool isArgExpr(unsigned Arg) const { - return Arg < NumArgs && getArg(Arg).is(); + return Arg < NumArgs && isa(getArg(Arg)); } - Expr *getArgAsExpr(unsigned Arg) const { - return getArg(Arg).get(); - } + Expr *getArgAsExpr(unsigned Arg) const { return cast(getArg(Arg)); } bool isArgIdent(unsigned Arg) const { - return Arg < NumArgs && getArg(Arg).is(); + return Arg < NumArgs && isa(getArg(Arg)); } IdentifierLoc *getArgAsIdent(unsigned Arg) const { - return getArg(Arg).get(); + return cast(getArg(Arg)); } const AvailabilityChange &getAvailabilityIntroduced() const { diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index b8684d11460ed..ae07ed8478f2a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -5314,7 +5314,7 @@ class Sema final : public SemaBase { /// is complete. void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc, - Expr *Init); + ExprResult Init); /// Handle a C++ member initializer using parentheses syntax. MemInitResult diff --git a/clang/include/clang/Sema/SemaConcept.h b/clang/include/clang/Sema/SemaConcept.h index 4b1abccb7741a..fa5309a597b3a 100644 --- a/clang/include/clang/Sema/SemaConcept.h +++ b/clang/include/clang/Sema/SemaConcept.h @@ -210,17 +210,17 @@ bool subsumes(const NormalForm &PDNF, const NormalForm &QCNF, bool Found = false; for (NormalFormConstraint Pia : Pi) { for (NormalFormConstraint Qjb : Qj) { - if (Pia.is() && - Qjb.is()) { - if (Pia.get()->subsumes( - *Qjb.get(), E)) { + if (isa(Pia) && + isa(Qjb)) { + if (cast(Pia)->subsumes( + *cast(Qjb), E)) { Found = true; break; } - } else if (Pia.is() && - Qjb.is()) { - if (E(*Pia.get(), - *Qjb.get())) { + } else if (isa(Pia) && + isa(Qjb)) { + if (E(*cast(Pia), + *cast(Qjb))) { Found = true; break; } diff --git a/clang/include/clang/Sema/SemaHLSL.h b/clang/include/clang/Sema/SemaHLSL.h index ee685d95c9615..f4cd11f423a84 100644 --- a/clang/include/clang/Sema/SemaHLSL.h +++ b/clang/include/clang/Sema/SemaHLSL.h @@ -119,6 +119,7 @@ class SemaHLSL : public SemaBase { void handleNumThreadsAttr(Decl *D, const ParsedAttr &AL); void handleWaveSizeAttr(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); void handlePackOffsetAttr(Decl *D, const ParsedAttr &AL); void handleShaderAttr(Decl *D, const ParsedAttr &AL); diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h index 41d05b2bfb078..27cda71989726 100644 --- a/clang/include/clang/Sema/SemaInternal.h +++ b/clang/include/clang/Sema/SemaInternal.h @@ -75,7 +75,7 @@ getDepthAndIndex(UnexpandedParameterPack UPP) { if (const auto *TTP = UPP.first.dyn_cast()) return std::make_pair(TTP->getDepth(), TTP->getIndex()); - return getDepthAndIndex(UPP.first.get()); + return getDepthAndIndex(cast(UPP.first)); } class TypoCorrectionConsumer : public VisibleDeclConsumer { diff --git a/clang/include/clang/Sema/SemaOpenACC.h b/clang/include/clang/Sema/SemaOpenACC.h index d720cf3c74d87..4b92af507af4e 100644 --- a/clang/include/clang/Sema/SemaOpenACC.h +++ b/clang/include/clang/Sema/SemaOpenACC.h @@ -164,9 +164,14 @@ class SemaOpenACC : public SemaBase { } /// If there is a current 'active' loop construct with a 'gang' clause on a - /// 'kernel' construct, this will have the source location for it. This - /// permits us to implement the restriction of no further 'gang' clauses. - SourceLocation LoopGangClauseOnKernelLoc; + /// 'kernel' construct, this will have the source location for it, and the + /// 'kernel kind'. This permits us to implement the restriction of no further + /// 'gang' clauses. + struct LoopGangOnKernelTy { + SourceLocation Loc; + OpenACCDirectiveKind DirKind = OpenACCDirectiveKind::Invalid; + } LoopGangClauseOnKernel; + /// If there is a current 'active' loop construct with a 'worker' clause on it /// (on any sort of construct), this has the source location for it. This /// permits us to implement the restriction of no further 'gang' or 'worker' @@ -394,6 +399,9 @@ class SemaOpenACC : public SemaBase { ClauseKind == OpenACCClauseKind::PCreate || ClauseKind == OpenACCClauseKind::PresentOrCreate || ClauseKind == OpenACCClauseKind::Attach || + ClauseKind == OpenACCClauseKind::Delete || + ClauseKind == OpenACCClauseKind::UseDevice || + ClauseKind == OpenACCClauseKind::Detach || ClauseKind == OpenACCClauseKind::DevicePtr || ClauseKind == OpenACCClauseKind::Reduction || ClauseKind == OpenACCClauseKind::FirstPrivate) && @@ -530,6 +538,9 @@ class SemaOpenACC : public SemaBase { ClauseKind == OpenACCClauseKind::PCreate || ClauseKind == OpenACCClauseKind::PresentOrCreate || ClauseKind == OpenACCClauseKind::Attach || + ClauseKind == OpenACCClauseKind::Delete || + ClauseKind == OpenACCClauseKind::UseDevice || + ClauseKind == OpenACCClauseKind::Detach || ClauseKind == OpenACCClauseKind::DevicePtr || ClauseKind == OpenACCClauseKind::FirstPrivate) && "Parsed clause kind does not have a var-list"); @@ -566,6 +577,9 @@ class SemaOpenACC : public SemaBase { ClauseKind == OpenACCClauseKind::PCreate || ClauseKind == OpenACCClauseKind::PresentOrCreate || ClauseKind == OpenACCClauseKind::Attach || + ClauseKind == OpenACCClauseKind::Delete || + ClauseKind == OpenACCClauseKind::UseDevice || + ClauseKind == OpenACCClauseKind::Detach || ClauseKind == OpenACCClauseKind::DevicePtr || ClauseKind == OpenACCClauseKind::FirstPrivate) && "Parsed clause kind does not have a var-list"); @@ -648,7 +662,8 @@ class SemaOpenACC : public SemaBase { /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES /// happen before any associated declarations or statements have been parsed. /// This function is only called when we are parsing a 'statement' context. - bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc); + bool ActOnStartStmtDirective(OpenACCDirectiveKind K, SourceLocation StartLoc, + ArrayRef Clauses); /// Called after the directive, including its clauses, have been parsed and /// parsing has consumed the 'annot_pragma_openacc_end' token. This DOES @@ -705,12 +720,15 @@ class SemaOpenACC : public SemaBase { ExprResult CheckTileSizeExpr(Expr *SizeExpr); // Check a single expression on a gang clause. - ExprResult CheckGangExpr(OpenACCGangKind GK, Expr *E); + ExprResult CheckGangExpr(ArrayRef ExistingClauses, + OpenACCDirectiveKind DK, OpenACCGangKind GK, + Expr *E); // Does the checking for a 'gang' clause that needs to be done in dependent // and not dependent cases. OpenACCClause * - CheckGangClause(ArrayRef ExistingClauses, + CheckGangClause(OpenACCDirectiveKind DirKind, + ArrayRef ExistingClauses, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef GangKinds, ArrayRef IntExprs, SourceLocation EndLoc); @@ -771,7 +789,7 @@ class SemaOpenACC : public SemaBase { SemaOpenACC &SemaRef; ComputeConstructInfo OldActiveComputeConstructInfo; OpenACCDirectiveKind DirKind; - SourceLocation OldLoopGangClauseOnKernelLoc; + LoopGangOnKernelTy OldLoopGangClauseOnKernel; SourceLocation OldLoopWorkerClauseLoc; SourceLocation OldLoopVectorClauseLoc; LoopWithoutSeqCheckingInfo OldLoopWithoutSeqInfo; diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h index 6872d04cc4dfb..9800f75f676aa 100644 --- a/clang/include/clang/Sema/Template.h +++ b/clang/include/clang/Sema/Template.h @@ -486,10 +486,10 @@ enum class TemplateSubstitutionKind : char { const Decl *D = I->first; llvm::PointerUnion &Stored = newScope->LocalDecls[D]; - if (I->second.is()) { - Stored = I->second.get(); + if (auto *D2 = dyn_cast(I->second)) { + Stored = D2; } else { - DeclArgumentPack *OldPack = I->second.get(); + DeclArgumentPack *OldPack = cast(I->second); DeclArgumentPack *NewPack = new DeclArgumentPack(*OldPack); Stored = NewPack; newScope->ArgumentPacks.push_back(NewPack); diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h index fd834c14ce790..da0e5fdb117aa 100644 --- a/clang/include/clang/Serialization/ASTBitCodes.h +++ b/clang/include/clang/Serialization/ASTBitCodes.h @@ -724,15 +724,20 @@ enum ASTRecordTypes { /// Record code for vtables to emit. VTABLES_TO_EMIT = 70, - /// Record code for the FunctionDecl to lambdas mapping. These lambdas have to - /// be loaded right after the function they belong to. It is required to have - /// canonical declaration for the lambda class from the same module as - /// enclosing function. - FUNCTION_DECL_TO_LAMBDAS_MAP = 71, + /// Record code for related declarations that have to be deserialized together + /// from the same module. + RELATED_DECLS_MAP = 71, /// Record code for Sema's vector of functions/blocks with effects to /// be verified. DECLS_WITH_EFFECTS_TO_VERIFY = 72, + + /// Record code for updated specialization + UPDATE_SPECIALIZATION = 73, + + CXX_ADDED_TEMPLATE_SPECIALIZATION = 74, + + CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION = 75, }; /// Record types used within a source manager block. @@ -1502,6 +1507,12 @@ enum DeclCode { /// An ImplicitConceptSpecializationDecl record. DECL_IMPLICIT_CONCEPT_SPECIALIZATION, + // A decls specilization record. + DECL_SPECIALIZATIONS, + + // A decls specilization record. + DECL_PARTIAL_SPECIALIZATIONS, + DECL_LAST = DECL_IMPLICIT_CONCEPT_SPECIALIZATION }; @@ -2006,6 +2017,10 @@ enum StmtCode { STMT_OPENACC_LOOP_CONSTRUCT, STMT_OPENACC_COMBINED_CONSTRUCT, EXPR_OPENACC_ASTERISK_SIZE, + STMT_OPENACC_DATA_CONSTRUCT, + STMT_OPENACC_ENTER_DATA_CONSTRUCT, + STMT_OPENACC_EXIT_DATA_CONSTRUCT, + STMT_OPENACC_HOST_DATA_CONSTRUCT, // HLSL Constructs EXPR_HLSL_OUT_ARG, diff --git a/clang/include/clang/Serialization/ASTReader.h b/clang/include/clang/Serialization/ASTReader.h index f739fe688c110..9f978762a6fb6 100644 --- a/clang/include/clang/Serialization/ASTReader.h +++ b/clang/include/clang/Serialization/ASTReader.h @@ -354,6 +354,9 @@ class ASTIdentifierLookupTrait; /// The on-disk hash table(s) used for DeclContext name lookup. struct DeclContextLookupTable; +/// The on-disk hash table(s) used for specialization decls. +struct LazySpecializationInfoLookupTable; + } // namespace reader } // namespace serialization @@ -534,17 +537,14 @@ class ASTReader /// namespace as if it is not delayed. DelayedNamespaceOffsetMapTy DelayedNamespaceOffsetMap; - /// Mapping from FunctionDecl IDs to the corresponding lambda IDs. + /// Mapping from main decl ID to the related decls IDs. /// - /// These lambdas have to be loaded right after the function they belong to. - /// It is required to have canonical declaration for lambda class from the - /// same module as enclosing function. This is required to correctly resolve - /// captured variables in the lambda. Without this, due to lazy - /// deserialization, canonical declarations for the function and lambdas can - /// be selected from different modules and DeclRefExprs may refer to the AST - /// nodes that don't exist in the function. - llvm::DenseMap> - FunctionToLambdasMap; + /// These related decls have to be loaded right after the main decl. + /// It is required to have canonical declaration for related decls from the + /// same module as the enclosing main decl. Without this, due to lazy + /// deserialization, canonical declarations for the main decl and related can + /// be selected from different modules. + llvm::DenseMap> RelatedDeclsMap; struct PendingUpdateRecord { Decl *D; @@ -632,20 +632,40 @@ class ASTReader llvm::DenseMap Lookups; + using SpecLookupTableTy = + llvm::DenseMap; + /// Map from decls to specialized decls. + SpecLookupTableTy SpecializationsLookups; + /// Split partial specialization from specialization to speed up lookups. + SpecLookupTableTy PartialSpecializationsLookups; + + bool LoadExternalSpecializationsImpl(SpecLookupTableTy &SpecLookups, + const Decl *D); + bool LoadExternalSpecializationsImpl(SpecLookupTableTy &SpecLookups, + const Decl *D, + ArrayRef TemplateArgs); + // Updates for visible decls can occur for other contexts than just the // TU, and when we read those update records, the actual context may not // be available yet, so have this pending map using the ID as a key. It - // will be realized when the context is actually loaded. - struct PendingVisibleUpdate { + // will be realized when the data is actually loaded. + struct UpdateData { ModuleFile *Mod; const unsigned char *Data; }; - using DeclContextVisibleUpdates = SmallVector; + using DeclContextVisibleUpdates = SmallVector; /// Updates to the visible declarations of declaration contexts that /// haven't been loaded yet. llvm::DenseMap PendingVisibleUpdates; + using SpecializationsUpdate = SmallVector; + using SpecializationsUpdateMap = + llvm::DenseMap; + SpecializationsUpdateMap PendingSpecializationsUpdates; + SpecializationsUpdateMap PendingPartialSpecializationsUpdates; + /// The set of C++ or Objective-C classes that have forward /// declarations that have not yet been linked to their definitions. llvm::SmallPtrSet PendingDefinitions; @@ -678,6 +698,11 @@ class ASTReader llvm::BitstreamCursor &Cursor, uint64_t Offset, GlobalDeclID ID); + bool ReadSpecializations(ModuleFile &M, llvm::BitstreamCursor &Cursor, + uint64_t Offset, Decl *D, bool IsPartial); + void AddSpecializations(const Decl *D, const unsigned char *Data, + ModuleFile &M, bool IsPartial); + /// A vector containing identifiers that have already been /// loaded. /// @@ -1419,6 +1444,14 @@ class ASTReader const serialization::reader::DeclContextLookupTable * getLoadedLookupTables(DeclContext *Primary) const; + /// Get the loaded specializations lookup tables for \p D, + /// if any. + serialization::reader::LazySpecializationInfoLookupTable * + getLoadedSpecializationsLookupTables(const Decl *D, bool IsPartial); + + /// If we have any unloaded specialization for \p D + bool haveUnloadedSpecializations(const Decl *D) const; + private: struct ImportedModule { ModuleFile *Mod; @@ -2076,6 +2109,12 @@ class ASTReader unsigned BlockID, uint64_t *StartOfBlockOffset = nullptr); + bool LoadExternalSpecializations(const Decl *D, bool OnlyPartial) override; + + bool + LoadExternalSpecializations(const Decl *D, + ArrayRef TemplateArgs) override; + /// Finds all the visible declarations with a given name. /// The current implementation of this method just loads the entire /// lookup table as unmaterialized references. diff --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h index e418fdea44a0a..cb972f0106402 100644 --- a/clang/include/clang/Serialization/ASTWriter.h +++ b/clang/include/clang/Serialization/ASTWriter.h @@ -230,13 +230,12 @@ class ASTWriter : public ASTDeserializationListener, /// instead of comparing the result of `getDeclID()` or `GetDeclRef()`. llvm::SmallPtrSet PredefinedDecls; - /// Mapping from FunctionDecl ID to the list of lambda IDs inside the - /// function. + /// Mapping from the main decl to related decls inside the main decls. /// - /// These lambdas have to be loaded right after the function they belong to. - /// In order to have canonical declaration for lambda class from the same - /// module as enclosing function during deserialization. - llvm::DenseMap> FunctionToLambdasMap; + /// These related decls have to be loaded right after the main decl they + /// belong to. In order to have canonical declaration for related decls from + /// the same module as the main decl during deserialization. + llvm::DenseMap> RelatedDeclsMap; /// Offset of each declaration in the bitstream, indexed by /// the declaration's ID. @@ -423,6 +422,13 @@ class ASTWriter : public ASTDeserializationListener, /// Only meaningful for reduced BMI. DeclUpdateMap DeclUpdatesFromGMF; + /// Mapping from decl templates and its new specialization in the + /// current TU. + using SpecializationUpdateMap = + llvm::MapVector>; + SpecializationUpdateMap SpecializationsUpdates; + SpecializationUpdateMap PartialSpecializationsUpdates; + using FirstLatestDeclMap = llvm::DenseMap; /// Map of first declarations from a chained PCH that point to the @@ -575,6 +581,12 @@ class ASTWriter : public ASTDeserializationListener, bool isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC); + void GenerateSpecializationInfoLookupTable( + const NamedDecl *D, llvm::SmallVectorImpl &Specializations, + llvm::SmallVectorImpl &LookupTable, bool IsPartial); + uint64_t WriteSpecializationInfoLookupTable( + const NamedDecl *D, llvm::SmallVectorImpl &Specializations, + bool IsPartial); void GenerateNameLookupTable(ASTContext &Context, const DeclContext *DC, llvm::SmallVectorImpl &LookupTable); uint64_t WriteDeclContextLexicalBlock(ASTContext &Context, @@ -590,6 +602,7 @@ class ASTWriter : public ASTDeserializationListener, void WriteDeclAndTypes(ASTContext &Context); void PrepareWritingSpecialDecls(Sema &SemaRef); void WriteSpecialDeclRecords(Sema &SemaRef); + void WriteSpecializationsUpdates(bool IsPartial); void WriteDeclUpdatesBlocks(ASTContext &Context, RecordDataImpl &OffsetsRecord); void WriteDeclContextVisibleUpdate(ASTContext &Context, @@ -619,6 +632,9 @@ class ASTWriter : public ASTDeserializationListener, unsigned DeclEnumAbbrev = 0; unsigned DeclObjCIvarAbbrev = 0; unsigned DeclCXXMethodAbbrev = 0; + unsigned DeclSpecializationsAbbrev = 0; + unsigned DeclPartialSpecializationsAbbrev = 0; + unsigned DeclDependentNonTemplateCXXMethodAbbrev = 0; unsigned DeclTemplateCXXMethodAbbrev = 0; unsigned DeclMemberSpecializedCXXMethodAbbrev = 0; diff --git a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td index 9be82622f264c..b34e940682fc5 100644 --- a/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ b/clang/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -1749,6 +1749,10 @@ def UncountedLambdaCapturesChecker : Checker<"UncountedLambdaCapturesChecker">, let ParentPackage = WebKitAlpha in { +def MemoryUnsafeCastChecker : Checker<"MemoryUnsafeCastChecker">, + HelpText<"Check for memory unsafe casts from base type to derived type.">, + Documentation; + def NoUncheckedPtrMemberChecker : Checker<"NoUncheckedPtrMemberChecker">, HelpText<"Check for no unchecked member variables.">, Documentation; diff --git a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def index ad2dbffe88326..d8a7c755c9596 100644 --- a/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def +++ b/clang/include/clang/StaticAnalyzer/Core/AnalyzerOptions.def @@ -189,20 +189,29 @@ ANALYZER_OPTION( "crosscheck-with-z3-eqclass-timeout-threshold", "Set a timeout for bug report equivalence classes in milliseconds. " "If we exhaust this threshold, we will drop the bug report eqclass " - "instead of doing more Z3 queries. Set 0 for no timeout.", 700) + "instead of doing more Z3 queries. Setting this to 700 ms in conjunction " + "with \"crosscheck-with-z3-timeout-threshold\" of 300 ms, would nicely " + "guarantee that no bug report equivalence class can take longer than " + "1 second, effectively mitigating Z3 hangs during refutation. " + "Set 0 for no timeout.", 0) ANALYZER_OPTION( unsigned, Z3CrosscheckTimeoutThreshold, "crosscheck-with-z3-timeout-threshold", "Set a timeout for individual Z3 queries in milliseconds. " - "Set 0 for no timeout.", 300) + "On fast machines, 300 worked well in some cases. " + "The lower it is, the higher the chances of having flaky issues. " + "Having no timeout may hang the analyzer indefinitely. " + "Set 0 for no timeout.", 15'000) ANALYZER_OPTION( unsigned, Z3CrosscheckRLimitThreshold, "crosscheck-with-z3-rlimit-threshold", - "Set the Z3 resource limit threshold. This sets a deterministic cutoff " - "point for Z3 queries, as longer queries usually consume more resources. " - "Set 0 for unlimited.", 400'000) + "Set the Z3 resource limit threshold. This sets a supposedly deterministic " + "cutoff point for Z3 queries, as longer queries usually consume more " + "resources. " + "400'000 should on average make Z3 queries run for up to 100ms on modern " + "hardware. Set 0 for unlimited.", 0) ANALYZER_OPTION(bool, ShouldReportIssuesInMainSourceFile, "report-in-main-source-file", diff --git a/clang/include/module.modulemap b/clang/include/module.modulemap index b399f0beee59a..5bb9f6b7a91f6 100644 --- a/clang/include/module.modulemap +++ b/clang/include/module.modulemap @@ -115,7 +115,7 @@ module Clang_Diagnostics { module Driver { header "clang/Driver/DriverDiagnostic.h" export * } module Frontend { header "clang/Frontend/FrontendDiagnostic.h" export * } module Lex { header "clang/Lex/LexDiagnostic.h" export * } - module Parse { header "clang/Parse/ParseDiagnostic.h" export * } + module Parse { header "clang/Basic/DiagnosticParse.h" export * } module Serialization { header "clang/Serialization/SerializationDiagnostic.h" export * } module Refactoring { header "clang/Tooling/Refactoring/RefactoringDiagnostic.h" export * } } @@ -183,9 +183,14 @@ module Clang_StaticAnalyzer_Frontend { module * { export * } } +module Clang_Support { requires cplusplus umbrella "clang/Support" module * { export * } } + module Clang_Testing { requires cplusplus umbrella "clang/Testing" + + textual header "clang/Testing/TestLanguage.def" + module * { export * } } diff --git a/clang/lib/APINotes/APINotesFormat.h b/clang/lib/APINotes/APINotesFormat.h index a03cef36294db..939235179c363 100644 --- a/clang/lib/APINotes/APINotesFormat.h +++ b/clang/lib/APINotes/APINotesFormat.h @@ -24,7 +24,7 @@ const uint16_t VERSION_MAJOR = 0; /// API notes file minor version number. /// /// When the format changes IN ANY WAY, this number should be incremented. -const uint16_t VERSION_MINOR = 33; // SwiftEscapable +const uint16_t VERSION_MINOR = 34; // SwiftReturnOwnership const uint8_t kSwiftConforms = 1; const uint8_t kSwiftDoesNotConform = 2; diff --git a/clang/lib/APINotes/APINotesManager.cpp b/clang/lib/APINotes/APINotesManager.cpp index 039d09fa7cf57..70d96c735503f 100644 --- a/clang/lib/APINotes/APINotesManager.cpp +++ b/clang/lib/APINotes/APINotesManager.cpp @@ -374,9 +374,9 @@ APINotesManager::findAPINotes(SourceLocation Loc) { ++NumDirectoryCacheHits; // We've been redirected to another directory for answers. Follow it. - if (Known->second && Known->second.is()) { + if (Known->second && isa(Known->second)) { DirsVisited.insert(*Dir); - Dir = Known->second.get(); + Dir = cast(Known->second); continue; } diff --git a/clang/lib/APINotes/APINotesReader.cpp b/clang/lib/APINotes/APINotesReader.cpp index 45a344c13f470..fa06dffdd14b0 100644 --- a/clang/lib/APINotes/APINotesReader.cpp +++ b/clang/lib/APINotes/APINotesReader.cpp @@ -373,6 +373,13 @@ void ReadFunctionInfo(const uint8_t *&Data, FunctionInfo &Info) { endian::readNext(Data); Info.ResultType = std::string(Data, Data + ResultTypeLen); Data += ResultTypeLen; + + unsigned SwiftReturnOwnershipLength = + endian::readNext(Data); + Info.SwiftReturnOwnership = std::string(reinterpret_cast(Data), + reinterpret_cast(Data) + + SwiftReturnOwnershipLength); + Data += SwiftReturnOwnershipLength; } /// Used to deserialize the on-disk Objective-C method table. diff --git a/clang/lib/APINotes/APINotesTypes.cpp b/clang/lib/APINotes/APINotesTypes.cpp index d06277fa36727..f726faa832bcc 100644 --- a/clang/lib/APINotes/APINotesTypes.cpp +++ b/clang/lib/APINotes/APINotesTypes.cpp @@ -77,6 +77,8 @@ LLVM_DUMP_METHOD void FunctionInfo::dump(llvm::raw_ostream &OS) const { << "RawRetainCountConvention: " << RawRetainCountConvention << ' '; if (!ResultType.empty()) OS << "Result Type: " << ResultType << ' '; + if (!SwiftReturnOwnership.empty()) + OS << "SwiftReturnOwnership: " << SwiftReturnOwnership << ' '; if (!Params.empty()) OS << '\n'; for (auto &PI : Params) diff --git a/clang/lib/APINotes/APINotesWriter.cpp b/clang/lib/APINotes/APINotesWriter.cpp index 480e1190358d4..1aae07bbdd30e 100644 --- a/clang/lib/APINotes/APINotesWriter.cpp +++ b/clang/lib/APINotes/APINotesWriter.cpp @@ -1093,6 +1093,7 @@ unsigned getFunctionInfoSize(const FunctionInfo &FI) { for (const auto &P : FI.Params) size += getParamInfoSize(P); size += sizeof(uint16_t) + FI.ResultType.size(); + size += sizeof(uint16_t) + FI.SwiftReturnOwnership.size(); return size; } @@ -1118,6 +1119,9 @@ void emitFunctionInfo(raw_ostream &OS, const FunctionInfo &FI) { writer.write(FI.ResultType.size()); writer.write(ArrayRef{FI.ResultType.data(), FI.ResultType.size()}); + writer.write(FI.SwiftReturnOwnership.size()); + writer.write(ArrayRef{FI.SwiftReturnOwnership.data(), + FI.SwiftReturnOwnership.size()}); } /// Used to serialize the on-disk global function table. diff --git a/clang/lib/APINotes/APINotesYAMLCompiler.cpp b/clang/lib/APINotes/APINotesYAMLCompiler.cpp index 0668dda910f2a..414a59a4f12d0 100644 --- a/clang/lib/APINotes/APINotesYAMLCompiler.cpp +++ b/clang/lib/APINotes/APINotesYAMLCompiler.cpp @@ -162,6 +162,7 @@ struct Method { bool DesignatedInit = false; bool Required = false; StringRef ResultType; + StringRef SwiftReturnOwnership; }; typedef std::vector MethodsSeq; @@ -196,6 +197,8 @@ template <> struct MappingTraits { IO.mapOptional("DesignatedInit", M.DesignatedInit, false); IO.mapOptional("Required", M.Required, false); IO.mapOptional("ResultType", M.ResultType, StringRef("")); + IO.mapOptional("SwiftReturnOwnership", M.SwiftReturnOwnership, + StringRef("")); } }; } // namespace yaml @@ -291,6 +294,7 @@ struct Function { StringRef SwiftName; StringRef Type; StringRef ResultType; + StringRef SwiftReturnOwnership; }; typedef std::vector FunctionsSeq; @@ -313,6 +317,8 @@ template <> struct MappingTraits { IO.mapOptional("SwiftPrivate", F.SwiftPrivate); IO.mapOptional("SwiftName", F.SwiftName, StringRef("")); IO.mapOptional("ResultType", F.ResultType, StringRef("")); + IO.mapOptional("SwiftReturnOwnership", F.SwiftReturnOwnership, + StringRef("")); } }; } // namespace yaml @@ -825,6 +831,7 @@ class YAMLConverter { emitError("'FactoryAsInit' is no longer valid; use 'SwiftName' instead"); MI.ResultType = std::string(M.ResultType); + MI.SwiftReturnOwnership = std::string(M.SwiftReturnOwnership); // Translate parameter information. convertParams(M.Params, MI, MI.Self); @@ -950,6 +957,7 @@ class YAMLConverter { convertNullability(Function.Nullability, Function.NullabilityOfRet, FI, Function.Name); FI.ResultType = std::string(Function.ResultType); + FI.SwiftReturnOwnership = std::string(Function.SwiftReturnOwnership); FI.setRetainCountConvention(Function.RetainCountConvention); } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 80e8c5b9df58e..6ec927e13a755 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -112,6 +112,27 @@ enum FloatingRank { Ibm128Rank }; +template <> struct llvm::DenseMapInfo { + static FoldingSetNodeID getEmptyKey() { return FoldingSetNodeID{}; } + + static FoldingSetNodeID getTombstoneKey() { + FoldingSetNodeID id; + for (size_t i = 0; i < sizeof(id) / sizeof(unsigned); ++i) { + id.AddInteger(std::numeric_limits::max()); + } + return id; + } + + static unsigned getHashValue(const FoldingSetNodeID &Val) { + return Val.ComputeHash(); + } + + static bool isEqual(const FoldingSetNodeID &LHS, + const FoldingSetNodeID &RHS) { + return LHS == RHS; + } +}; + /// \returns The locations that are relevant when searching for Doc comments /// related to \p D. static SmallVector @@ -899,7 +920,7 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM, FunctionProtoTypes(this_(), FunctionProtoTypesLog2InitSize), DependentTypeOfExprTypes(this_()), DependentDecltypeTypes(this_()), TemplateSpecializationTypes(this_()), - DependentTemplateSpecializationTypes(this_()), AutoTypes(this_()), + DependentTemplateSpecializationTypes(this_()), DependentBitIntTypes(this_()), SubstTemplateTemplateParmPacks(this_()), DeducedTemplates(this_()), ArrayParameterTypes(this_()), CanonTemplateTemplateParms(this_()), SourceMgr(SM), LangOpts(LOpts), @@ -6294,12 +6315,14 @@ QualType ASTContext::getAutoTypeInternal( return getAutoDeductType(); // Look in the folding set for an existing type. - void *InsertPos = nullptr; llvm::FoldingSetNodeID ID; - AutoType::Profile(ID, *this, DeducedType, Keyword, IsDependent, - TypeConstraintConcept, TypeConstraintArgs); - if (AutoType *AT = AutoTypes.FindNodeOrInsertPos(ID, InsertPos)) - return QualType(AT, 0); + bool IsDeducedDependent = + !DeducedType.isNull() && DeducedType->isDependentType(); + AutoType::Profile(ID, *this, DeducedType, Keyword, + IsDependent || IsDeducedDependent, TypeConstraintConcept, + TypeConstraintArgs); + if (auto const AT_iter = AutoTypes.find(ID); AT_iter != AutoTypes.end()) + return QualType(AT_iter->getSecond(), 0); QualType Canon; if (!IsCanon) { @@ -6314,10 +6337,6 @@ QualType ASTContext::getAutoTypeInternal( Canon = getAutoTypeInternal(QualType(), Keyword, IsDependent, IsPack, CanonicalConcept, CanonicalConceptArgs, true); - // Find the insert position again. - [[maybe_unused]] auto *Nothing = - AutoTypes.FindNodeOrInsertPos(ID, InsertPos); - assert(!Nothing && "canonical type broken"); } } } @@ -6331,8 +6350,13 @@ QualType ASTContext::getAutoTypeInternal( : TypeDependence::None) | (IsPack ? TypeDependence::UnexpandedPack : TypeDependence::None), Canon, TypeConstraintConcept, TypeConstraintArgs); +#ifndef NDEBUG + llvm::FoldingSetNodeID InsertedID; + AT->Profile(InsertedID, *this); + assert(InsertedID == ID && "ID does not match"); +#endif Types.push_back(AT); - AutoTypes.InsertNode(AT, InsertPos); + AutoTypes.try_emplace(ID, AT); return QualType(AT, 0); } diff --git a/clang/lib/AST/ByteCode/BitcastBuffer.cpp b/clang/lib/AST/ByteCode/BitcastBuffer.cpp index 0cc97b0b6bf19..fbd500fd8f5f4 100644 --- a/clang/lib/AST/ByteCode/BitcastBuffer.cpp +++ b/clang/lib/AST/ByteCode/BitcastBuffer.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// #include "BitcastBuffer.h" +#include "llvm/ADT/STLExtras.h" using namespace clang; using namespace clang::interp; @@ -60,6 +61,80 @@ BitcastBuffer::copyBits(Bits BitOffset, Bits BitWidth, Bits FullBitWidth, return Out; } +bool BitcastBuffer::allInitialized() const { + return rangeInitialized(Bits::zero(), FinalBitSize); +} + +void BitcastBuffer::markInitialized(Bits Offset, Bits Length) { + if (Length.isZero()) + return; + + BitRange Element(Offset, Offset + Length - Bits(1)); + if (InitializedBits.empty()) { + InitializedBits.push_back(Element); + return; + } + + assert(InitializedBits.size() >= 1); + // Common case of just appending. + Bits End = InitializedBits.back().End; + if (End <= Offset) { + // Merge this range with the last one. + // In the best-case scenario, this means we only ever have + // one single bit range covering all bits. + if (End == (Offset - Bits(1))) { + InitializedBits.back().End = Element.End; + return; + } + + // Otherwise, we can simply append. + InitializedBits.push_back(Element); + } else { + // Insert sorted. + auto It = std::upper_bound(InitializedBits.begin(), InitializedBits.end(), + Element); + InitializedBits.insert(It, Element); + } + +#ifndef NDEBUG + // Ensure ranges are sorted and non-overlapping. + assert(llvm::is_sorted(InitializedBits)); + for (unsigned I = 1; I != InitializedBits.size(); ++I) { + [[maybe_unused]] auto Prev = InitializedBits[I - 1]; + [[maybe_unused]] auto Cur = InitializedBits[I]; + assert(Prev.End.N < Cur.Start.N); + } +#endif +} + +bool BitcastBuffer::rangeInitialized(Bits Offset, Bits Length) const { + if (Length.isZero()) + return true; + + BitRange Range(Offset, Offset + Length - Bits(1)); + Bits Sum; + bool FoundStart = false; + for (BitRange BR : InitializedBits) { + if (FoundStart) { + if (BR.contains(Range.End)) { + Sum += (Range.End - BR.Start + Bits(1)); + break; + } + + // Else, BR is completely inside Range. + Sum += BR.size(); + } + if (BR.contains(Range.Start)) { + Sum += (BR.End - Range.Start + Bits(1)); + FoundStart = true; + } + } + + // Note that Sum can be larger than Range, e.g. when Range is fully + // contained in one range. + return Sum >= Range.size(); +} + #if 0 template static std::string hex(T t) { diff --git a/clang/lib/AST/ByteCode/BitcastBuffer.h b/clang/lib/AST/ByteCode/BitcastBuffer.h index c7b170ceb168f..d1d6ee39ad17b 100644 --- a/clang/lib/AST/ByteCode/BitcastBuffer.h +++ b/clang/lib/AST/ByteCode/BitcastBuffer.h @@ -8,6 +8,7 @@ #ifndef LLVM_CLANG_AST_INTERP_BITCAST_BUFFER_H #define LLVM_CLANG_AST_INTERP_BITCAST_BUFFER_H +#include "llvm/ADT/SmallVector.h" #include #include #include @@ -17,6 +18,8 @@ namespace interp { enum class Endian { Little, Big }; +struct Bytes; + /// A quantity in bits. struct Bits { size_t N = 0; @@ -29,15 +32,23 @@ struct Bits { bool isFullByte() const { return N % 8 == 0; } bool nonZero() const { return N != 0; } bool isZero() const { return N == 0; } + Bytes toBytes() const; - Bits operator-(Bits Other) { return Bits(N - Other.N); } - Bits operator+(Bits Other) { return Bits(N + Other.N); } + Bits operator-(Bits Other) const { return Bits(N - Other.N); } + Bits operator+(Bits Other) const { return Bits(N + Other.N); } Bits operator+=(size_t O) { N += O; return *this; } + Bits operator+=(Bits O) { + N += O.N; + return *this; + } - bool operator>=(Bits Other) { return N >= Other.N; } + bool operator>=(Bits Other) const { return N >= Other.N; } + bool operator<=(Bits Other) const { return N <= Other.N; } + bool operator==(Bits Other) const { return N == Other.N; } + bool operator!=(Bits Other) const { return N != Other.N; } }; /// A quantity in bytes. @@ -48,11 +59,29 @@ struct Bytes { Bits toBits() const { return Bits(N * 8); } }; +inline Bytes Bits::toBytes() const { + assert(isFullByte()); + return Bytes(N / 8); +} + +/// A bit range. Both Start and End are inclusive. +struct BitRange { + Bits Start; + Bits End; + + BitRange(Bits Start, Bits End) : Start(Start), End(End) {} + Bits size() const { return End - Start + Bits(1); } + bool operator<(BitRange Other) const { return Start.N < Other.Start.N; } + + bool contains(Bits B) { return Start <= B && End >= B; } +}; + /// Track what bits have been initialized to known values and which ones /// have indeterminate value. struct BitcastBuffer { Bits FinalBitSize; std::unique_ptr Data; + llvm::SmallVector InitializedBits; BitcastBuffer(Bits FinalBitSize) : FinalBitSize(FinalBitSize) { assert(FinalBitSize.isFullByte()); @@ -62,12 +91,14 @@ struct BitcastBuffer { /// Returns the buffer size in bits. Bits size() const { return FinalBitSize; } + Bytes byteSize() const { return FinalBitSize.toBytes(); } /// Returns \c true if all bits in the buffer have been initialized. - bool allInitialized() const { - // FIXME: Implement. - return true; - } + bool allInitialized() const; + /// Marks the bits in the given range as initialized. + /// FIXME: Can we do this automatically in pushData()? + void markInitialized(Bits Start, Bits Length); + bool rangeInitialized(Bits Offset, Bits Length) const; /// Push \p BitWidth bits at \p BitOffset from \p In into the buffer. /// \p TargetEndianness is the endianness of the target we're compiling for. diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 900312401bbda..7f6295e126dcf 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -6483,6 +6483,7 @@ bool Compiler::emitBuiltinBitCast(const CastExpr *E) { QualType ToType = E->getType(); std::optional ToT = classify(ToType); + // Bitcasting TO nullptr_t is always fine. if (ToType->isNullPtrType()) { if (!this->discard(SubExpr)) return false; @@ -6490,12 +6491,6 @@ bool Compiler::emitBuiltinBitCast(const CastExpr *E) { return this->emitNullPtr(0, nullptr, E); } - if (FromType->isNullPtrType() && ToT) { - if (!this->discard(SubExpr)) - return false; - - return visitZeroInitializer(*ToT, ToType, E); - } assert(!ToType->isReferenceType()); // Prepare storage for the result in case we discard. diff --git a/clang/lib/AST/ByteCode/Integral.h b/clang/lib/AST/ByteCode/Integral.h index 26585799e5ead..13fdb5369f2b7 100644 --- a/clang/lib/AST/ByteCode/Integral.h +++ b/clang/lib/AST/ByteCode/Integral.h @@ -179,7 +179,10 @@ template class Integral final { unsigned countLeadingZeros() const { if constexpr (!Signed) return llvm::countl_zero(V); - llvm_unreachable("Don't call countLeadingZeros() on signed types."); + if (isPositive()) + return llvm::countl_zero( + static_cast(V)); + llvm_unreachable("Don't call countLeadingZeros() on negative values."); } Integral truncate(unsigned TruncBits) const { @@ -210,7 +213,7 @@ template class Integral final { return Integral(Value.V); } - static Integral zero() { return from(0); } + static Integral zero(unsigned BitWidth = 0) { return from(0); } template static Integral from(T Value, unsigned NumBits) { return Integral(Value); diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp index 435af1201890c..7c7752080746e 100644 --- a/clang/lib/AST/ByteCode/Interp.cpp +++ b/clang/lib/AST/ByteCode/Interp.cpp @@ -1360,7 +1360,10 @@ bool CallVirt(InterpState &S, CodePtr OpPC, const Function *Func, bool CallBI(InterpState &S, CodePtr OpPC, const Function *Func, const CallExpr *CE, uint32_t BuiltinID) { - if (S.checkingPotentialConstantExpression()) + // A little arbitrary, but the current interpreter allows evaluation + // of builtin functions in this mode, with some exceptions. + if (BuiltinID == Builtin::BI__builtin_operator_new && + S.checkingPotentialConstantExpression()) return false; auto NewFrame = std::make_unique(S, Func, OpPC); diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h index c5c2a5ef19cc4..f085f96fdf539 100644 --- a/clang/lib/AST/ByteCode/Interp.h +++ b/clang/lib/AST/ByteCode/Interp.h @@ -14,6 +14,7 @@ #define LLVM_CLANG_AST_INTERP_INTERP_H #include "../ExprConstShared.h" +#include "BitcastBuffer.h" #include "Boolean.h" #include "DynamicAllocator.h" #include "FixedPoint.h" @@ -2510,50 +2511,52 @@ inline bool DoShift(InterpState &S, CodePtr OpPC, LT &LHS, RT &RHS) { S, OpPC, LHS, RHS); } - if constexpr (Dir == ShiftDir::Left) { - if (LHS.isNegative() && !S.getLangOpts().CPlusPlus20) { - // C++11 [expr.shift]p2: A signed left shift must have a non-negative - // operand, and must not overflow the corresponding unsigned type. - // C++2a [expr.shift]p2: E1 << E2 is the unique value congruent to - // E1 x 2^E2 module 2^N. - const SourceInfo &Loc = S.Current->getSource(OpPC); - S.CCEDiag(Loc, diag::note_constexpr_lshift_of_negative) << LHS.toAPSInt(); - if (!S.noteUndefinedBehavior()) - return false; - } - } - if (!CheckShift(S, OpPC, LHS, RHS, Bits)) return false; // Limit the shift amount to Bits - 1. If this happened, // it has already been diagnosed by CheckShift() above, // but we still need to handle it. + // Note that we have to be extra careful here since we're doing the shift in + // any case, but we need to adjust the shift amount or the way we do the shift + // for the potential error cases. typename LT::AsUnsigned R; + unsigned MaxShiftAmount = LHS.bitWidth() - 1; if constexpr (Dir == ShiftDir::Left) { - if (RHS > RT::from(Bits - 1, RHS.bitWidth())) - LT::AsUnsigned::shiftLeft(LT::AsUnsigned::from(LHS), - LT::AsUnsigned::from(Bits - 1), Bits, &R); - else + if (Compare(RHS, RT::from(MaxShiftAmount, RHS.bitWidth())) == + ComparisonCategoryResult::Greater) { + if (LHS.isNegative()) + R = LT::AsUnsigned::zero(LHS.bitWidth()); + else { + RHS = RT::from(LHS.countLeadingZeros(), RHS.bitWidth()); + LT::AsUnsigned::shiftLeft(LT::AsUnsigned::from(LHS), + LT::AsUnsigned::from(RHS, Bits), Bits, &R); + } + } else if (LHS.isNegative()) { + if (LHS.isMin()) { + R = LT::AsUnsigned::zero(LHS.bitWidth()); + } else { + // If the LHS is negative, perform the cast and invert the result. + typename LT::AsUnsigned LHSU = LT::AsUnsigned::from(-LHS); + LT::AsUnsigned::shiftLeft(LHSU, LT::AsUnsigned::from(RHS, Bits), Bits, + &R); + R = -R; + } + } else { + // The good case, a simple left shift. LT::AsUnsigned::shiftLeft(LT::AsUnsigned::from(LHS), LT::AsUnsigned::from(RHS, Bits), Bits, &R); + } } else { - if (RHS > RT::from(Bits - 1, RHS.bitWidth())) - LT::AsUnsigned::shiftRight(LT::AsUnsigned::from(LHS), - LT::AsUnsigned::from(Bits - 1), Bits, &R); - else - LT::AsUnsigned::shiftRight(LT::AsUnsigned::from(LHS), - LT::AsUnsigned::from(RHS, Bits), Bits, &R); - } - - // We did the shift above as unsigned. Restore the sign bit if we need to. - if constexpr (Dir == ShiftDir::Right) { - if (LHS.isSigned() && LHS.isNegative()) { - typename LT::AsUnsigned SignBit; - LT::AsUnsigned::shiftLeft(LT::AsUnsigned::from(1, Bits), - LT::AsUnsigned::from(Bits - 1, Bits), Bits, - &SignBit); - LT::AsUnsigned::bitOr(R, SignBit, Bits, &R); + // Right shift. + if (Compare(RHS, RT::from(MaxShiftAmount, RHS.bitWidth())) == + ComparisonCategoryResult::Greater) { + R = LT::AsUnsigned::from(-1); + } else { + // Do the shift on potentially signed LT, then convert to unsigned type. + LT A; + LT::shiftRight(LHS, LT::from(RHS, Bits), Bits, &A); + R = LT::AsUnsigned::from(A); } } @@ -3050,7 +3053,16 @@ inline bool BitCast(InterpState &S, CodePtr OpPC, bool TargetIsUCharOrByte, llvm::SmallVector Buff(BuffSize); bool HasIndeterminateBits = false; - if (!DoBitCast(S, OpPC, FromPtr, Buff.data(), BuffSize, HasIndeterminateBits)) + Bits FullBitWidth(ResultBitWidth); + Bits BitWidth = FullBitWidth; + + if constexpr (std::is_same_v) { + assert(Sem); + BitWidth = Bits(llvm::APFloatBase::getSizeInBits(*Sem)); + } + + if (!DoBitCast(S, OpPC, FromPtr, Buff.data(), BitWidth, FullBitWidth, + HasIndeterminateBits)) return false; if (!CheckBitCast(S, OpPC, HasIndeterminateBits, TargetIsUCharOrByte)) @@ -3058,16 +3070,7 @@ inline bool BitCast(InterpState &S, CodePtr OpPC, bool TargetIsUCharOrByte, if constexpr (std::is_same_v) { assert(Sem); - ptrdiff_t Offset = 0; - - if (llvm::sys::IsBigEndianHost) { - unsigned NumBits = llvm::APFloatBase::getSizeInBits(*Sem); - assert(NumBits % 8 == 0); - assert(NumBits <= ResultBitWidth); - Offset = (ResultBitWidth - NumBits) / 8; - } - - S.Stk.push(T::bitcastFromMemory(Buff.data() + Offset, *Sem)); + S.Stk.push(T::bitcastFromMemory(Buff.data(), *Sem)); } else { assert(!Sem); S.Stk.push(T::bitcastFromMemory(Buff.data(), ResultBitWidth)); diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 24b630d0455e1..d6b33c8aeeaac 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -197,9 +197,19 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, const Pointer &A = getParam(Frame, 0); const Pointer &B = getParam(Frame, 1); - if (ID == Builtin::BIstrcmp) + if (ID == Builtin::BIstrcmp || ID == Builtin::BIstrncmp) diagnoseNonConstexprBuiltin(S, OpPC, ID); + uint64_t Limit = ~static_cast(0); + if (ID == Builtin::BIstrncmp || ID == Builtin::BI__builtin_strncmp) + Limit = peekToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2))) + .getZExtValue(); + + if (Limit == 0) { + pushInteger(S, 0, Call->getType()); + return true; + } + if (!CheckLive(S, OpPC, A, AK_Read) || !CheckLive(S, OpPC, B, AK_Read)) return false; @@ -212,7 +222,11 @@ static bool interp__builtin_strcmp(InterpState &S, CodePtr OpPC, unsigned IndexA = A.getIndex(); unsigned IndexB = B.getIndex(); int32_t Result = 0; - for (;; ++IndexA, ++IndexB) { + uint64_t Steps = 0; + for (;; ++IndexA, ++IndexB, ++Steps) { + + if (Steps >= Limit) + break; const Pointer &PA = A.atIndex(IndexA); const Pointer &PB = B.atIndex(IndexB); if (!CheckRange(S, OpPC, PA, AK_Read) || @@ -243,7 +257,7 @@ static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, unsigned ID = Func->getBuiltinID(); const Pointer &StrPtr = getParam(Frame, 0); - if (ID == Builtin::BIstrlen) + if (ID == Builtin::BIstrlen || ID == Builtin::BIwcslen) diagnoseNonConstexprBuiltin(S, OpPC, ID); if (!CheckArray(S, OpPC, StrPtr)) @@ -256,6 +270,12 @@ static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, return false; assert(StrPtr.getFieldDesc()->isPrimitiveArray()); + unsigned ElemSize = StrPtr.getFieldDesc()->getElemSize(); + + if (ID == Builtin::BI__builtin_wcslen || ID == Builtin::BIwcslen) { + [[maybe_unused]] const ASTContext &AC = S.getASTContext(); + assert(ElemSize == AC.getTypeSizeInChars(AC.getWCharType()).getQuantity()); + } size_t Len = 0; for (size_t I = StrPtr.getIndex();; ++I, ++Len) { @@ -264,7 +284,20 @@ static bool interp__builtin_strlen(InterpState &S, CodePtr OpPC, if (!CheckRange(S, OpPC, ElemPtr, AK_Read)) return false; - uint8_t Val = ElemPtr.deref(); + uint32_t Val; + switch (ElemSize) { + case 1: + Val = ElemPtr.deref(); + break; + case 2: + Val = ElemPtr.deref(); + break; + case 4: + Val = ElemPtr.deref(); + break; + default: + llvm_unreachable("Unsupported char size"); + } if (Val == 0) break; } @@ -1797,6 +1830,7 @@ static bool interp__builtin_elementwise_popcount(InterpState &S, CodePtr OpPC, return true; } + static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, const InterpFrame *Frame, const Function *Func, const CallExpr *Call) { @@ -1827,6 +1861,35 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, return false; } + QualType ElemType; + if (SrcPtr.getFieldDesc()->isArray()) + ElemType = SrcPtr.getFieldDesc()->getElemQualType(); + else + ElemType = SrcPtr.getType(); + + unsigned ElemSize = + S.getASTContext().getTypeSizeInChars(ElemType).getQuantity(); + if (Size.urem(ElemSize) != 0) { + S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_memcpy_unsupported) + << Move << /*IsWchar=*/false << 0 << ElemType << Size << ElemSize; + return false; + } + + // Check for overlapping memory regions. + if (!Move && Pointer::pointToSameBlock(SrcPtr, DestPtr)) { + unsigned SrcIndex = SrcPtr.getIndex() * SrcPtr.elemSize(); + unsigned DstIndex = DestPtr.getIndex() * DestPtr.elemSize(); + unsigned N = Size.getZExtValue(); + + if ((SrcIndex <= DstIndex && (SrcIndex + N) > DstIndex) || + (DstIndex <= SrcIndex && (DstIndex + N) > SrcIndex)) { + S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_memcpy_overlap) + << /*IsWChar=*/false; + return false; + } + } + // As a last resort, reject dummy pointers. if (DestPtr.isDummy() || SrcPtr.isDummy()) return false; @@ -1838,6 +1901,120 @@ static bool interp__builtin_memcpy(InterpState &S, CodePtr OpPC, return true; } +/// Determine if T is a character type for which we guarantee that +/// sizeof(T) == 1. +static bool isOneByteCharacterType(QualType T) { + return T->isCharType() || T->isChar8Type(); +} + +static bool interp__builtin_memcmp(InterpState &S, CodePtr OpPC, + const InterpFrame *Frame, + const Function *Func, const CallExpr *Call) { + assert(Call->getNumArgs() == 3); + unsigned ID = Func->getBuiltinID(); + const Pointer &PtrA = getParam(Frame, 0); + const Pointer &PtrB = getParam(Frame, 1); + const APSInt &Size = + peekToAPSInt(S.Stk, *S.getContext().classify(Call->getArg(2))); + + if (ID == Builtin::BImemcmp || ID == Builtin::BIbcmp || + ID == Builtin::BIwmemcmp) + diagnoseNonConstexprBuiltin(S, OpPC, ID); + + if (Size.isZero()) { + pushInteger(S, 0, Call->getType()); + return true; + } + + bool IsWide = + (ID == Builtin::BIwmemcmp || ID == Builtin::BI__builtin_wmemcmp); + + const ASTContext &ASTCtx = S.getASTContext(); + // FIXME: This is an arbitrary limitation the current constant interpreter + // had. We could remove this. + if (!IsWide && (!isOneByteCharacterType(PtrA.getType()) || + !isOneByteCharacterType(PtrB.getType()))) { + S.FFDiag(S.Current->getSource(OpPC), + diag::note_constexpr_memcmp_unsupported) + << ("'" + ASTCtx.BuiltinInfo.getName(ID) + "'").str() << PtrA.getType() + << PtrB.getType(); + return false; + } + + if (PtrA.isDummy() || PtrB.isDummy()) + return false; + + // Now, read both pointers to a buffer and compare those. + BitcastBuffer BufferA( + Bits(ASTCtx.getTypeSize(PtrA.getFieldDesc()->getType()))); + readPointerToBuffer(S.getContext(), PtrA, BufferA, false); + // FIXME: The swapping here is UNDOING something we do when reading the + // data into the buffer. + if (ASTCtx.getTargetInfo().isBigEndian()) + swapBytes(BufferA.Data.get(), BufferA.byteSize().getQuantity()); + + BitcastBuffer BufferB( + Bits(ASTCtx.getTypeSize(PtrB.getFieldDesc()->getType()))); + readPointerToBuffer(S.getContext(), PtrB, BufferB, false); + // FIXME: The swapping here is UNDOING something we do when reading the + // data into the buffer. + if (ASTCtx.getTargetInfo().isBigEndian()) + swapBytes(BufferB.Data.get(), BufferB.byteSize().getQuantity()); + + size_t MinBufferSize = std::min(BufferA.byteSize().getQuantity(), + BufferB.byteSize().getQuantity()); + + unsigned ElemSize = 1; + if (IsWide) + ElemSize = ASTCtx.getTypeSizeInChars(ASTCtx.getWCharType()).getQuantity(); + // The Size given for the wide variants is in wide-char units. Convert it + // to bytes. + size_t ByteSize = Size.getZExtValue() * ElemSize; + size_t CmpSize = std::min(MinBufferSize, ByteSize); + + for (size_t I = 0; I != CmpSize; I += ElemSize) { + if (IsWide) { + INT_TYPE_SWITCH(*S.getContext().classify(ASTCtx.getWCharType()), { + T A = *reinterpret_cast(BufferA.Data.get() + I); + T B = *reinterpret_cast(BufferB.Data.get() + I); + if (A < B) { + pushInteger(S, -1, Call->getType()); + return true; + } else if (A > B) { + pushInteger(S, 1, Call->getType()); + return true; + } + }); + } else { + std::byte A = BufferA.Data[I]; + std::byte B = BufferB.Data[I]; + + if (A < B) { + pushInteger(S, -1, Call->getType()); + return true; + } else if (A > B) { + pushInteger(S, 1, Call->getType()); + return true; + } + } + } + + // We compared CmpSize bytes above. If the limiting factor was the Size + // passed, we're done and the result is equality (0). + if (ByteSize <= CmpSize) { + pushInteger(S, 0, Call->getType()); + return true; + } + + // However, if we read all the available bytes but were instructed to read + // even more, diagnose this as a "read of dereferenced one-past-the-end + // pointer". This is what would happen if we called CheckRead() on every array + // element. + S.FFDiag(S.Current->getSource(OpPC), diag::note_constexpr_access_past_end) + << AK_Read << S.Current->getRange(OpPC); + return false; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, const CallExpr *Call, uint32_t BuiltinID) { const InterpFrame *Frame = S.Current; @@ -1854,11 +2031,15 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, break; case Builtin::BI__builtin_strcmp: case Builtin::BIstrcmp: + case Builtin::BI__builtin_strncmp: + case Builtin::BIstrncmp: if (!interp__builtin_strcmp(S, OpPC, Frame, F, Call)) return false; break; case Builtin::BI__builtin_strlen: case Builtin::BIstrlen: + case Builtin::BI__builtin_wcslen: + case Builtin::BIwcslen: if (!interp__builtin_strlen(S, OpPC, Frame, F, Call)) return false; break; @@ -2307,6 +2488,16 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const Function *F, return false; break; + case Builtin::BI__builtin_memcmp: + case Builtin::BImemcmp: + case Builtin::BI__builtin_bcmp: + case Builtin::BIbcmp: + case Builtin::BI__builtin_wmemcmp: + case Builtin::BIwmemcmp: + if (!interp__builtin_memcmp(S, OpPC, Frame, F, Call)) + return false; + break; + default: S.FFDiag(S.Current->getLocation(OpPC), diag::note_invalid_subexpr_in_const_expr) diff --git a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp index 03c556cd70bb7..07f7694370821 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp @@ -33,8 +33,9 @@ using namespace clang::interp; // bytes to/from the buffer. /// Used to iterate over pointer fields. -using DataFunc = llvm::function_ref; +using DataFunc = + llvm::function_ref; #define BITCAST_TYPE_SWITCH(Expr, B) \ do { \ @@ -72,11 +73,6 @@ using DataFunc = llvm::function_refisPrimitive()) - return F(P, FieldDesc->getPrimType(), Offset, /*PackedBools=*/false); + if (FieldDesc->isPrimitive()) { + Bits FullBitWidth = + Bits(Ctx.getASTContext().getTypeSize(FieldDesc->getType())); + return F(P, FieldDesc->getPrimType(), Offset, FullBitWidth, + /*PackedBools=*/false); + } // Primitive arrays. if (FieldDesc->isPrimitiveArray()) { QualType ElemType = FieldDesc->getElemQualType(); - size_t ElemSizeInBits = Ctx.getASTContext().getTypeSize(ElemType); + Bits ElemSize = Bits(Ctx.getASTContext().getTypeSize(ElemType)); PrimType ElemT = *Ctx.classify(ElemType); // Special case, since the bools here are packed. bool PackedBools = FieldDesc->getType()->isExtVectorBoolType(); unsigned NumElems = FieldDesc->getNumElems(); bool Ok = true; for (unsigned I = P.getIndex(); I != NumElems; ++I) { - Ok = Ok && F(P.atIndex(I), ElemT, Offset, PackedBools); - Offset += PackedBools ? 1 : ElemSizeInBits; + Ok = Ok && F(P.atIndex(I), ElemT, Offset, ElemSize, PackedBools); + Offset += PackedBools ? Bits(1) : ElemSize; if (Offset >= BitsToRead) break; } @@ -109,10 +109,10 @@ static bool enumerateData(const Pointer &P, const Context &Ctx, Bits Offset, // Composite arrays. if (FieldDesc->isCompositeArray()) { QualType ElemType = FieldDesc->getElemQualType(); - size_t ElemSizeInBits = Ctx.getASTContext().getTypeSize(ElemType); + Bits ElemSize = Bits(Ctx.getASTContext().getTypeSize(ElemType)); for (unsigned I = 0; I != FieldDesc->getNumElems(); ++I) { enumerateData(P.atIndex(I).narrow(), Ctx, Offset, BitsToRead, F); - Offset += ElemSizeInBits; + Offset += ElemSize; if (Offset >= BitsToRead) break; } @@ -222,44 +222,75 @@ static bool CheckBitcastType(InterpState &S, CodePtr OpPC, QualType T, IsToType)) return false; + if (const auto *VT = T->getAs()) { + const ASTContext &ASTCtx = S.getASTContext(); + QualType EltTy = VT->getElementType(); + unsigned NElts = VT->getNumElements(); + unsigned EltSize = + VT->isExtVectorBoolType() ? 1 : ASTCtx.getTypeSize(EltTy); + + if ((NElts * EltSize) % ASTCtx.getCharWidth() != 0) { + // The vector's size in bits is not a multiple of the target's byte size, + // so its layout is unspecified. For now, we'll simply treat these cases + // as unsupported (this should only be possible with OpenCL bool vectors + // whose element count isn't a multiple of the byte size). + const Expr *E = S.Current->getExpr(OpPC); + S.FFDiag(E, diag::note_constexpr_bit_cast_invalid_vector) + << QualType(VT, 0) << EltSize << NElts << ASTCtx.getCharWidth(); + return false; + } + + if (EltTy->isRealFloatingType() && + &ASTCtx.getFloatTypeSemantics(EltTy) == &APFloat::x87DoubleExtended()) { + // The layout for x86_fp80 vectors seems to be handled very inconsistently + // by both clang and LLVM, so for now we won't allow bit_casts involving + // it in a constexpr context. + const Expr *E = S.Current->getExpr(OpPC); + S.FFDiag(E, diag::note_constexpr_bit_cast_unsupported_type) << EltTy; + return false; + } + } + return true; } -static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr, - BitcastBuffer &Buffer, bool ReturnOnUninit) { +bool clang::interp::readPointerToBuffer(const Context &Ctx, + const Pointer &FromPtr, + BitcastBuffer &Buffer, + bool ReturnOnUninit) { const ASTContext &ASTCtx = Ctx.getASTContext(); Endian TargetEndianness = ASTCtx.getTargetInfo().isLittleEndian() ? Endian::Little : Endian::Big; return enumeratePointerFields( FromPtr, Ctx, Buffer.size(), - [&](const Pointer &P, PrimType T, Bits BitOffset, + [&](const Pointer &P, PrimType T, Bits BitOffset, Bits FullBitWidth, bool PackedBools) -> bool { - CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars(P.getType()); - Bits BitWidth = Bits(ASTCtx.toBits(ObjectReprChars)); - Bits FullBitWidth = BitWidth; + Bits BitWidth = FullBitWidth; - if (const FieldDecl *FD = P.getField(); FD && FD->isBitField()) { + if (const FieldDecl *FD = P.getField(); FD && FD->isBitField()) BitWidth = Bits(std::min(FD->getBitWidthValue(ASTCtx), (unsigned)FullBitWidth.getQuantity())); - } else if (T == PT_Bool && PackedBools) + else if (T == PT_Bool && PackedBools) BitWidth = Bits(1); if (BitWidth.isZero()) return true; - if (!P.isInitialized()) { - assert(false && "Implement uninitialized value tracking"); - return ReturnOnUninit; + // Bits will be left uninitialized and diagnosed when reading. + if (!P.isInitialized()) + return true; + + if (T == PT_Ptr) { + assert(P.getType()->isNullPtrType()); + // Clang treats nullptr_t has having NO bits in its value + // representation. So, we accept it here and leave its bits + // uninitialized. + return true; } assert(P.isInitialized()); - // nullptr_t is a PT_Ptr for us, but it's still not std::is_pointer_v. - if (T == PT_Ptr) - assert(false && "Implement casting to pointer types"); - - auto Buff = - std::make_unique(ObjectReprChars.getQuantity()); + auto Buff = std::make_unique(FullBitWidth.roundToBytes()); // Work around floating point types that contain unused padding bytes. // This is really just `long double` on x86, which is the only // fundamental type with padding bytes. @@ -275,11 +306,13 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr, if (llvm::sys::IsBigEndianHost) swapBytes(Buff.get(), NumBits.roundToBytes()); + Buffer.markInitialized(BitOffset, NumBits); } else { BITCAST_TYPE_SWITCH(T, { P.deref().bitcastToMemory(Buff.get()); }); if (llvm::sys::IsBigEndianHost) swapBytes(Buff.get(), FullBitWidth.roundToBytes()); + Buffer.markInitialized(BitOffset, BitWidth); } Buffer.pushData(Buff.get(), BitOffset, BitWidth, TargetEndianness); @@ -288,30 +321,34 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr, } bool clang::interp::DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr, - std::byte *Buff, size_t BuffSize, + std::byte *Buff, Bits BitWidth, Bits FullBitWidth, bool &HasIndeterminateBits) { assert(Ptr.isLive()); assert(Ptr.isBlockPointer()); assert(Buff); + assert(BitWidth <= FullBitWidth); + assert(FullBitWidth.isFullByte()); + assert(BitWidth.isFullByte()); - Bits BitSize = Bytes(BuffSize).toBits(); - BitcastBuffer Buffer(BitSize); + BitcastBuffer Buffer(FullBitWidth); + size_t BuffSize = FullBitWidth.roundToBytes(); if (!CheckBitcastType(S, OpPC, Ptr.getType(), /*IsToType=*/false)) return false; bool Success = readPointerToBuffer(S.getContext(), Ptr, Buffer, /*ReturnOnUninit=*/false); - HasIndeterminateBits = !Buffer.allInitialized(); + HasIndeterminateBits = !Buffer.rangeInitialized(Bits::zero(), BitWidth); const ASTContext &ASTCtx = S.getASTContext(); Endian TargetEndianness = ASTCtx.getTargetInfo().isLittleEndian() ? Endian::Little : Endian::Big; - auto B = Buffer.copyBits(Bits::zero(), BitSize, BitSize, TargetEndianness); + auto B = + Buffer.copyBits(Bits::zero(), BitWidth, FullBitWidth, TargetEndianness); std::memcpy(Buff, B.get(), BuffSize); if (llvm::sys::IsBigEndianHost) - swapBytes(Buff, BuffSize); + swapBytes(Buff, BitWidth.roundToBytes()); return Success; } @@ -348,12 +385,11 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC, ASTCtx.getTargetInfo().isLittleEndian() ? Endian::Little : Endian::Big; bool Success = enumeratePointerFields( ToPtr, S.getContext(), Buffer.size(), - [&](const Pointer &P, PrimType T, Bits BitOffset, + [&](const Pointer &P, PrimType T, Bits BitOffset, Bits FullBitWidth, bool PackedBools) -> bool { - CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars(P.getType()); - Bits FullBitWidth = Bits(ASTCtx.toBits(ObjectReprChars)); + QualType PtrType = P.getType(); if (T == PT_Float) { - const auto &Semantics = ASTCtx.getFloatTypeSemantics(P.getType()); + const auto &Semantics = ASTCtx.getFloatTypeSemantics(PtrType); Bits NumBits = Bits(llvm::APFloatBase::getSizeInBits(Semantics)); assert(NumBits.isFullByte()); assert(NumBits.getQuantity() <= FullBitWidth.getQuantity()); @@ -377,6 +413,23 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC, else BitWidth = FullBitWidth; + // If any of the bits are uninitialized, we need to abort unless the + // target type is std::byte or unsigned char. + bool Initialized = Buffer.rangeInitialized(BitOffset, BitWidth); + if (!Initialized) { + if (!PtrType->isStdByteType() && + !PtrType->isSpecificBuiltinType(BuiltinType::UChar) && + !PtrType->isSpecificBuiltinType(BuiltinType::Char_U)) { + const Expr *E = S.Current->getExpr(OpPC); + S.FFDiag(E, diag::note_constexpr_bit_cast_indet_dest) + << PtrType << S.getLangOpts().CharIsSigned + << E->getSourceRange(); + + return false; + } + return true; + } + auto Memory = Buffer.copyBits(BitOffset, BitWidth, FullBitWidth, TargetEndianness); if (llvm::sys::IsBigEndianHost) diff --git a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.h b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.h index 8142e0bf28fcf..b45613b2f21e2 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltinBitCast.h +++ b/clang/lib/AST/ByteCode/InterpBuiltinBitCast.h @@ -6,9 +6,10 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_AST_INTERP_BUILITN_BIT_CAST_H -#define LLVM_CLANG_AST_INTERP_BUILITN_BIT_CAST_H +#ifndef LLVM_CLANG_AST_INTERP_BUILTIN_BIT_CAST_H +#define LLVM_CLANG_AST_INTERP_BUILTIN_BIT_CAST_H +#include "BitcastBuffer.h" #include namespace clang { @@ -16,14 +17,22 @@ namespace interp { class Pointer; class InterpState; class CodePtr; +class Context; + +inline static void swapBytes(std::byte *M, size_t N) { + for (size_t I = 0; I != (N / 2); ++I) + std::swap(M[I], M[N - 1 - I]); +} bool DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr, - std::byte *Buff, size_t BuffSize, bool &HasIndeterminateBits); + std::byte *Buff, Bits BitWidth, Bits FullBitWidth, + bool &HasIndeterminateBits); bool DoBitCastPtr(InterpState &S, CodePtr OpPC, const Pointer &FromPtr, Pointer &ToPtr); bool DoBitCastPtr(InterpState &S, CodePtr OpPC, const Pointer &FromPtr, Pointer &ToPtr, size_t Size); - +bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr, + BitcastBuffer &Buffer, bool ReturnOnUninit); } // namespace interp } // namespace clang diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp index 10b8d524ff897..ee5775837d535 100644 --- a/clang/lib/AST/CXXInheritance.cpp +++ b/clang/lib/AST/CXXInheritance.cpp @@ -368,8 +368,8 @@ bool CXXRecordDecl::FindBaseClass(const CXXBaseSpecifier *Specifier, const CXXRecordDecl *BaseRecord) { assert(BaseRecord->getCanonicalDecl() == BaseRecord && "User data for FindBaseClass is not canonical!"); - return Specifier->getType()->castAs()->getDecl() - ->getCanonicalDecl() == BaseRecord; + return cast(Specifier->getType()->getAsRecordDecl()) + ->getCanonicalDecl() == BaseRecord; } bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier, @@ -378,8 +378,8 @@ bool CXXRecordDecl::FindVirtualBaseClass(const CXXBaseSpecifier *Specifier, assert(BaseRecord->getCanonicalDecl() == BaseRecord && "User data for FindBaseClass is not canonical!"); return Specifier->isVirtual() && - Specifier->getType()->castAs()->getDecl() - ->getCanonicalDecl() == BaseRecord; + cast(Specifier->getType()->getAsRecordDecl()) + ->getCanonicalDecl() == BaseRecord; } static bool isOrdinaryMember(const NamedDecl *ND) { @@ -692,7 +692,7 @@ AddIndirectPrimaryBases(const CXXRecordDecl *RD, ASTContext &Context, "Cannot get indirect primary bases for class with dependent bases."); const CXXRecordDecl *BaseDecl = - cast(I.getType()->castAs()->getDecl()); + cast(I.getType()->getAsRecordDecl()); // Only bases with virtual bases participate in computing the // indirect primary virtual base classes. @@ -714,7 +714,7 @@ CXXRecordDecl::getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const { "Cannot get indirect primary bases for class with dependent bases."); const CXXRecordDecl *BaseDecl = - cast(I.getType()->castAs()->getDecl()); + cast(I.getType()->getAsRecordDecl()); // Only bases with virtual bases participate in computing the // indirect primary virtual base classes. diff --git a/clang/lib/AST/CommentLexer.cpp b/clang/lib/AST/CommentLexer.cpp index f0250fc9fd55e..ec9a5b480aa29 100644 --- a/clang/lib/AST/CommentLexer.cpp +++ b/clang/lib/AST/CommentLexer.cpp @@ -8,8 +8,8 @@ #include "clang/AST/CommentLexer.h" #include "clang/AST/CommentCommandTraits.h" -#include "clang/AST/CommentDiagnostic.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/DiagnosticComment.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ConvertUTF.h" diff --git a/clang/lib/AST/CommentParser.cpp b/clang/lib/AST/CommentParser.cpp index 61508fe886efc..12ed8e3f1b79a 100644 --- a/clang/lib/AST/CommentParser.cpp +++ b/clang/lib/AST/CommentParser.cpp @@ -8,9 +8,9 @@ #include "clang/AST/CommentParser.h" #include "clang/AST/CommentCommandTraits.h" -#include "clang/AST/CommentDiagnostic.h" #include "clang/AST/CommentSema.h" #include "clang/Basic/CharInfo.h" +#include "clang/Basic/DiagnosticComment.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/ErrorHandling.h" diff --git a/clang/lib/AST/CommentSema.cpp b/clang/lib/AST/CommentSema.cpp index 69eda00643a8f..bd2206bb8a3bc 100644 --- a/clang/lib/AST/CommentSema.cpp +++ b/clang/lib/AST/CommentSema.cpp @@ -9,9 +9,9 @@ #include "clang/AST/CommentSema.h" #include "clang/AST/Attr.h" #include "clang/AST/CommentCommandTraits.h" -#include "clang/AST/CommentDiagnostic.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclTemplate.h" +#include "clang/Basic/DiagnosticComment.h" #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceManager.h" #include "clang/Lex/Preprocessor.h" diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp index 1da3f26bf23cd..40ee3753c2422 100644 --- a/clang/lib/AST/DeclTemplate.cpp +++ b/clang/lib/AST/DeclTemplate.cpp @@ -16,7 +16,9 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" +#include "clang/AST/ExprCXX.h" #include "clang/AST/ExternalASTSource.h" +#include "clang/AST/ODRHash.h" #include "clang/AST/TemplateBase.h" #include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" @@ -348,26 +350,39 @@ RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() c return Common; } -void RedeclarableTemplateDecl::loadLazySpecializationsImpl() const { - // Grab the most recent declaration to ensure we've loaded any lazy - // redeclarations of this template. - CommonBase *CommonBasePtr = getMostRecentDecl()->getCommonPtr(); - if (CommonBasePtr->LazySpecializations) { - ASTContext &Context = getASTContext(); - GlobalDeclID *Specs = CommonBasePtr->LazySpecializations; - CommonBasePtr->LazySpecializations = nullptr; - unsigned SpecSize = (*Specs++).getRawValue(); - for (unsigned I = 0; I != SpecSize; ++I) - (void)Context.getExternalSource()->GetExternalDecl(Specs[I]); - } +void RedeclarableTemplateDecl::loadLazySpecializationsImpl( + bool OnlyPartial /*=false*/) const { + auto *ExternalSource = getASTContext().getExternalSource(); + if (!ExternalSource) + return; + + ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(), + OnlyPartial); + return; } -template +bool RedeclarableTemplateDecl::loadLazySpecializationsImpl( + ArrayRef Args, TemplateParameterList *TPL) const { + auto *ExternalSource = getASTContext().getExternalSource(); + if (!ExternalSource) + return false; + + // If TPL is not null, it implies that we're loading specializations for + // partial templates. We need to load all specializations in such cases. + if (TPL) + return ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(), + /*OnlyPartial=*/false); + + return ExternalSource->LoadExternalSpecializations(this->getCanonicalDecl(), + Args); +} + +template typename RedeclarableTemplateDecl::SpecEntryTraits::DeclType * -RedeclarableTemplateDecl::findSpecializationImpl( +RedeclarableTemplateDecl::findSpecializationLocally( llvm::FoldingSetVector &Specs, void *&InsertPos, - ProfileArguments&&... ProfileArgs) { - using SETraits = SpecEntryTraits; + ProfileArguments &&...ProfileArgs) { + using SETraits = RedeclarableTemplateDecl::SpecEntryTraits; llvm::FoldingSetNodeID ID; EntryType::Profile(ID, std::forward(ProfileArgs)..., @@ -376,6 +391,24 @@ RedeclarableTemplateDecl::findSpecializationImpl( return Entry ? SETraits::getDecl(Entry)->getMostRecentDecl() : nullptr; } +template +typename RedeclarableTemplateDecl::SpecEntryTraits::DeclType * +RedeclarableTemplateDecl::findSpecializationImpl( + llvm::FoldingSetVector &Specs, void *&InsertPos, + ProfileArguments &&...ProfileArgs) { + + if (auto *Found = findSpecializationLocally( + Specs, InsertPos, std::forward(ProfileArgs)...)) + return Found; + + if (!loadLazySpecializationsImpl( + std::forward(ProfileArgs)...)) + return nullptr; + + return findSpecializationLocally( + Specs, InsertPos, std::forward(ProfileArgs)...); +} + template void RedeclarableTemplateDecl::addSpecializationImpl( llvm::FoldingSetVector &Specializations, EntryType *Entry, @@ -384,10 +417,14 @@ void RedeclarableTemplateDecl::addSpecializationImpl( if (InsertPos) { #ifndef NDEBUG + auto Args = SETraits::getTemplateArgs(Entry); + // Due to hash collisions, it can happen that we load another template + // specialization with the same hash. This is fine, as long as the next + // call to findSpecializationImpl does not find a matching Decl for the + // template arguments. + loadLazySpecializationsImpl(Args); void *CorrectInsertPos; - assert(!findSpecializationImpl(Specializations, - CorrectInsertPos, - SETraits::getTemplateArgs(Entry)) && + assert(!findSpecializationImpl(Specializations, CorrectInsertPos, Args) && InsertPos == CorrectInsertPos && "given incorrect InsertPos for specialization"); #endif @@ -445,12 +482,14 @@ FunctionTemplateDecl::getSpecializations() const { FunctionDecl * FunctionTemplateDecl::findSpecialization(ArrayRef Args, void *&InsertPos) { - return findSpecializationImpl(getSpecializations(), InsertPos, Args); + auto *Common = getCommonPtr(); + return findSpecializationImpl(Common->Specializations, InsertPos, Args); } void FunctionTemplateDecl::addSpecialization( FunctionTemplateSpecializationInfo *Info, void *InsertPos) { - addSpecializationImpl(getSpecializations(), Info, + auto *Common = getCommonPtr(); + addSpecializationImpl(Common->Specializations, Info, InsertPos); } @@ -510,8 +549,9 @@ ClassTemplateDecl *ClassTemplateDecl::CreateDeserialized(ASTContext &C, DeclarationName(), nullptr, nullptr); } -void ClassTemplateDecl::LoadLazySpecializations() const { - loadLazySpecializationsImpl(); +void ClassTemplateDecl::LoadLazySpecializations( + bool OnlyPartial /*=false*/) const { + loadLazySpecializationsImpl(OnlyPartial); } llvm::FoldingSetVector & @@ -522,7 +562,7 @@ ClassTemplateDecl::getSpecializations() const { llvm::FoldingSetVector & ClassTemplateDecl::getPartialSpecializations() const { - LoadLazySpecializations(); + LoadLazySpecializations(/*PartialOnly = */ true); return getCommonPtr()->PartialSpecializations; } @@ -536,12 +576,15 @@ ClassTemplateDecl::newCommon(ASTContext &C) const { ClassTemplateSpecializationDecl * ClassTemplateDecl::findSpecialization(ArrayRef Args, void *&InsertPos) { - return findSpecializationImpl(getSpecializations(), InsertPos, Args); + auto *Common = getCommonPtr(); + return findSpecializationImpl(Common->Specializations, InsertPos, Args); } void ClassTemplateDecl::AddSpecialization(ClassTemplateSpecializationDecl *D, void *InsertPos) { - addSpecializationImpl(getSpecializations(), D, InsertPos); + auto *Common = getCommonPtr(); + addSpecializationImpl(Common->Specializations, D, + InsertPos); } ClassTemplatePartialSpecializationDecl * @@ -1259,8 +1302,9 @@ VarTemplateDecl *VarTemplateDecl::CreateDeserialized(ASTContext &C, DeclarationName(), nullptr, nullptr); } -void VarTemplateDecl::LoadLazySpecializations() const { - loadLazySpecializationsImpl(); +void VarTemplateDecl::LoadLazySpecializations( + bool OnlyPartial /*=false*/) const { + loadLazySpecializationsImpl(OnlyPartial); } llvm::FoldingSetVector & @@ -1271,7 +1315,7 @@ VarTemplateDecl::getSpecializations() const { llvm::FoldingSetVector & VarTemplateDecl::getPartialSpecializations() const { - LoadLazySpecializations(); + LoadLazySpecializations(/*PartialOnly = */ true); return getCommonPtr()->PartialSpecializations; } @@ -1285,12 +1329,14 @@ VarTemplateDecl::newCommon(ASTContext &C) const { VarTemplateSpecializationDecl * VarTemplateDecl::findSpecialization(ArrayRef Args, void *&InsertPos) { - return findSpecializationImpl(getSpecializations(), InsertPos, Args); + auto *Common = getCommonPtr(); + return findSpecializationImpl(Common->Specializations, InsertPos, Args); } void VarTemplateDecl::AddSpecialization(VarTemplateSpecializationDecl *D, void *InsertPos) { - addSpecializationImpl(getSpecializations(), D, InsertPos); + auto *Common = getCommonPtr(); + addSpecializationImpl(Common->Specializations, D, InsertPos); } VarTemplatePartialSpecializationDecl * diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index a4fb4d5a1f2ec..5a6738196d289 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1639,11 +1639,19 @@ SourceLocation CallExpr::getBeginLoc() const { if (const auto *OCE = dyn_cast(this)) return OCE->getBeginLoc(); + if (const auto *Method = + dyn_cast_if_present(getCalleeDecl()); + Method && Method->isExplicitObjectMemberFunction()) { + assert(getNumArgs() > 0 && getArg(0)); + return getArg(0)->getBeginLoc(); + } + SourceLocation begin = getCallee()->getBeginLoc(); if (begin.isInvalid() && getNumArgs() > 0 && getArg(0)) begin = getArg(0)->getBeginLoc(); return begin; } + SourceLocation CallExpr::getEndLoc() const { if (const auto *OCE = dyn_cast(this)) return OCE->getEndLoc(); diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 6b5b95aee3552..89c515e639276 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -7352,31 +7352,6 @@ class APValueToBufferConverter { const VectorType *VTy = Ty->castAs(); QualType EltTy = VTy->getElementType(); unsigned NElts = VTy->getNumElements(); - unsigned EltSize = - VTy->isExtVectorBoolType() ? 1 : Info.Ctx.getTypeSize(EltTy); - - if ((NElts * EltSize) % Info.Ctx.getCharWidth() != 0) { - // The vector's size in bits is not a multiple of the target's byte size, - // so its layout is unspecified. For now, we'll simply treat these cases - // as unsupported (this should only be possible with OpenCL bool vectors - // whose element count isn't a multiple of the byte size). - Info.FFDiag(BCE->getBeginLoc(), - diag::note_constexpr_bit_cast_invalid_vector) - << Ty.getCanonicalType() << EltSize << NElts - << Info.Ctx.getCharWidth(); - return false; - } - - if (EltTy->isRealFloatingType() && &Info.Ctx.getFloatTypeSemantics(EltTy) == - &APFloat::x87DoubleExtended()) { - // The layout for x86_fp80 vectors seems to be handled very inconsistently - // by both clang and LLVM, so for now we won't allow bit_casts involving - // it in a constexpr context. - Info.FFDiag(BCE->getBeginLoc(), - diag::note_constexpr_bit_cast_unsupported_type) - << EltTy; - return false; - } if (VTy->isExtVectorBoolType()) { // Special handling for OpenCL bool vectors: @@ -7643,28 +7618,6 @@ class BufferToAPValueConverter { unsigned EltSize = VTy->isExtVectorBoolType() ? 1 : Info.Ctx.getTypeSize(EltTy); - if ((NElts * EltSize) % Info.Ctx.getCharWidth() != 0) { - // The vector's size in bits is not a multiple of the target's byte size, - // so its layout is unspecified. For now, we'll simply treat these cases - // as unsupported (this should only be possible with OpenCL bool vectors - // whose element count isn't a multiple of the byte size). - Info.FFDiag(BCE->getBeginLoc(), - diag::note_constexpr_bit_cast_invalid_vector) - << QualType(VTy, 0) << EltSize << NElts << Info.Ctx.getCharWidth(); - return std::nullopt; - } - - if (EltTy->isRealFloatingType() && &Info.Ctx.getFloatTypeSemantics(EltTy) == - &APFloat::x87DoubleExtended()) { - // The layout for x86_fp80 vectors seems to be handled very inconsistently - // by both clang and LLVM, so for now we won't allow bit_casts involving - // it in a constexpr context. - Info.FFDiag(BCE->getBeginLoc(), - diag::note_constexpr_bit_cast_unsupported_type) - << EltTy; - return std::nullopt; - } - SmallVector Elts; Elts.reserve(NElts); if (VTy->isExtVectorBoolType()) { @@ -7793,6 +7746,32 @@ static bool checkBitCastConstexprEligibilityType(SourceLocation Loc, Info, Ctx, CheckingDest)) return false; + if (const auto *VTy = Ty->getAs()) { + QualType EltTy = VTy->getElementType(); + unsigned NElts = VTy->getNumElements(); + unsigned EltSize = VTy->isExtVectorBoolType() ? 1 : Ctx.getTypeSize(EltTy); + + if ((NElts * EltSize) % Ctx.getCharWidth() != 0) { + // The vector's size in bits is not a multiple of the target's byte size, + // so its layout is unspecified. For now, we'll simply treat these cases + // as unsupported (this should only be possible with OpenCL bool vectors + // whose element count isn't a multiple of the byte size). + Info->FFDiag(Loc, diag::note_constexpr_bit_cast_invalid_vector) + << QualType(VTy, 0) << EltSize << NElts << Ctx.getCharWidth(); + return false; + } + + if (EltTy->isRealFloatingType() && + &Ctx.getFloatTypeSemantics(EltTy) == &APFloat::x87DoubleExtended()) { + // The layout for x86_fp80 vectors seems to be handled very inconsistently + // by both clang and LLVM, so for now we won't allow bit_casts involving + // it in a constexpr context. + Info->FFDiag(Loc, diag::note_constexpr_bit_cast_unsupported_type) + << EltTy; + return false; + } + } + return true; } @@ -10172,7 +10151,9 @@ bool PointerExprEvaluator::VisitCXXNewExpr(const CXXNewExpr *E) { return false; IsNothrow = true; } else if (OperatorNew->isReservedGlobalPlacementOperator()) { - if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26) { + if (Info.CurrentCall->isStdFunction() || Info.getLangOpts().CPlusPlus26 || + (Info.CurrentCall->CanEvalMSConstexpr && + OperatorNew->hasAttr())) { if (!EvaluatePointer(E->getPlacementArg(0), Result, Info)) return false; if (Result.Designator.Invalid) @@ -11339,6 +11320,37 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) { return Success(APValue(ResultElements.data(), ResultElements.size()), E); } + case Builtin::BI__builtin_elementwise_add_sat: + case Builtin::BI__builtin_elementwise_sub_sat: { + APValue SourceLHS, SourceRHS; + if (!EvaluateAsRValue(Info, E->getArg(0), SourceLHS) || + !EvaluateAsRValue(Info, E->getArg(1), SourceRHS)) + return false; + + QualType DestEltTy = E->getType()->castAs()->getElementType(); + unsigned SourceLen = SourceLHS.getVectorLength(); + SmallVector ResultElements; + ResultElements.reserve(SourceLen); + + for (unsigned EltNum = 0; EltNum < SourceLen; ++EltNum) { + APSInt LHS = SourceLHS.getVectorElt(EltNum).getInt(); + APSInt RHS = SourceRHS.getVectorElt(EltNum).getInt(); + switch (E->getBuiltinCallee()) { + case Builtin::BI__builtin_elementwise_add_sat: + ResultElements.push_back(APValue( + APSInt(LHS.isSigned() ? LHS.sadd_sat(RHS) : RHS.uadd_sat(RHS), + DestEltTy->isUnsignedIntegerOrEnumerationType()))); + break; + case Builtin::BI__builtin_elementwise_sub_sat: + ResultElements.push_back(APValue( + APSInt(LHS.isSigned() ? LHS.ssub_sat(RHS) : RHS.usub_sat(RHS), + DestEltTy->isUnsignedIntegerOrEnumerationType()))); + break; + } + } + + return Success(APValue(ResultElements.data(), ResultElements.size()), E); + } } } @@ -13204,6 +13216,25 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E, return Success(Val.rotr(Amt.urem(Val.getBitWidth())), E); } + case Builtin::BI__builtin_elementwise_add_sat: { + APSInt LHS, RHS; + if (!EvaluateInteger(E->getArg(0), LHS, Info) || + !EvaluateInteger(E->getArg(1), RHS, Info)) + return false; + + APInt Result = LHS.isSigned() ? LHS.sadd_sat(RHS) : LHS.uadd_sat(RHS); + return Success(APSInt(Result, !LHS.isSigned()), E); + } + case Builtin::BI__builtin_elementwise_sub_sat: { + APSInt LHS, RHS; + if (!EvaluateInteger(E->getArg(0), LHS, Info) || + !EvaluateInteger(E->getArg(1), RHS, Info)) + return false; + + APInt Result = LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS); + return Success(APSInt(Result, !LHS.isSigned()), E); + } + case Builtin::BIstrlen: case Builtin::BIwcslen: // A call to strlen is not a constant expression. @@ -16484,7 +16515,7 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, const ASTContext &Ctx, bool &IsConst) { // Fast-path evaluations of integer literals, since we sometimes see files // containing vast quantities of these. - if (const IntegerLiteral *L = dyn_cast(Exp)) { + if (const auto *L = dyn_cast(Exp)) { Result.Val = APValue(APSInt(L->getValue(), L->getType()->isUnsignedIntegerType())); IsConst = true; @@ -16497,6 +16528,18 @@ static bool FastEvaluateAsRValue(const Expr *Exp, Expr::EvalResult &Result, return true; } + if (const auto *FL = dyn_cast(Exp)) { + Result.Val = APValue(FL->getValue()); + IsConst = true; + return true; + } + + if (const auto *L = dyn_cast(Exp)) { + Result.Val = APValue(Ctx.MakeIntValue(L->getValue(), L->getType())); + IsConst = true; + return true; + } + if (const auto *CE = dyn_cast(Exp)) { if (CE->hasAPValueResult()) { APValue APV = CE->getAPValueResult(); diff --git a/clang/lib/AST/ExternalASTSource.cpp b/clang/lib/AST/ExternalASTSource.cpp index 7a14cc7d50ed0..543846c0093af 100644 --- a/clang/lib/AST/ExternalASTSource.cpp +++ b/clang/lib/AST/ExternalASTSource.cpp @@ -96,6 +96,15 @@ ExternalASTSource::FindExternalVisibleDeclsByName(const DeclContext *DC, return false; } +bool ExternalASTSource::LoadExternalSpecializations(const Decl *D, bool) { + return false; +} + +bool ExternalASTSource::LoadExternalSpecializations( + const Decl *D, ArrayRef) { + return false; +} + void ExternalASTSource::completeVisibleDeclsMap(const DeclContext *DC) {} void ExternalASTSource::FindExternalLexicalDecls( diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp index 645ca6f0e7b71..7c5c287e6c15b 100644 --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -818,15 +818,20 @@ void ODRHash::AddDecl(const Decl *D) { AddDeclarationName(ND->getDeclName()); - const auto *Specialization = - dyn_cast(D); - AddBoolean(Specialization); - if (Specialization) { - const TemplateArgumentList &List = Specialization->getTemplateArgs(); - ID.AddInteger(List.size()); - for (const TemplateArgument &TA : List.asArray()) - AddTemplateArgument(TA); - } + // If this was a specialization we should take into account its template + // arguments. This helps to reduce collisions coming when visiting template + // specialization types (eg. when processing type template arguments). + ArrayRef Args; + if (auto *CTSD = dyn_cast(D)) + Args = CTSD->getTemplateArgs().asArray(); + else if (auto *VTSD = dyn_cast(D)) + Args = VTSD->getTemplateArgs().asArray(); + else if (auto *FD = dyn_cast(D)) + if (FD->getTemplateSpecializationArgs()) + Args = FD->getTemplateSpecializationArgs()->asArray(); + + for (auto &TA : Args) + AddTemplateArgument(TA); } namespace { diff --git a/clang/lib/AST/OpenACCClause.cpp b/clang/lib/AST/OpenACCClause.cpp index 1299e4f807ceb..fbc9f6d15fa7b 100644 --- a/clang/lib/AST/OpenACCClause.cpp +++ b/clang/lib/AST/OpenACCClause.cpp @@ -32,8 +32,10 @@ bool OpenACCClauseWithVarList::classof(const OpenACCClause *C) { return OpenACCPrivateClause::classof(C) || OpenACCFirstPrivateClause::classof(C) || OpenACCDevicePtrClause::classof(C) || - OpenACCDevicePtrClause::classof(C) || - OpenACCAttachClause::classof(C) || OpenACCNoCreateClause::classof(C) || + OpenACCDeleteClause::classof(C) || + OpenACCUseDeviceClause::classof(C) || + OpenACCDetachClause::classof(C) || OpenACCAttachClause::classof(C) || + OpenACCNoCreateClause::classof(C) || OpenACCPresentClause::classof(C) || OpenACCCopyClause::classof(C) || OpenACCCopyInClause::classof(C) || OpenACCCopyOutClause::classof(C) || OpenACCReductionClause::classof(C) || OpenACCCreateClause::classof(C); @@ -277,6 +279,36 @@ OpenACCAttachClause *OpenACCAttachClause::Create(const ASTContext &C, return new (Mem) OpenACCAttachClause(BeginLoc, LParenLoc, VarList, EndLoc); } +OpenACCDetachClause *OpenACCDetachClause::Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation LParenLoc, + ArrayRef VarList, + SourceLocation EndLoc) { + void *Mem = + C.Allocate(OpenACCDetachClause::totalSizeToAlloc(VarList.size())); + return new (Mem) OpenACCDetachClause(BeginLoc, LParenLoc, VarList, EndLoc); +} + +OpenACCDeleteClause *OpenACCDeleteClause::Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation LParenLoc, + ArrayRef VarList, + SourceLocation EndLoc) { + void *Mem = + C.Allocate(OpenACCDeleteClause::totalSizeToAlloc(VarList.size())); + return new (Mem) OpenACCDeleteClause(BeginLoc, LParenLoc, VarList, EndLoc); +} + +OpenACCUseDeviceClause *OpenACCUseDeviceClause::Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation LParenLoc, + ArrayRef VarList, + SourceLocation EndLoc) { + void *Mem = C.Allocate( + OpenACCUseDeviceClause::totalSizeToAlloc(VarList.size())); + return new (Mem) OpenACCUseDeviceClause(BeginLoc, LParenLoc, VarList, EndLoc); +} + OpenACCDevicePtrClause *OpenACCDevicePtrClause::Create(const ASTContext &C, SourceLocation BeginLoc, SourceLocation LParenLoc, @@ -444,6 +476,22 @@ OpenACCVectorClause *OpenACCVectorClause::Create(const ASTContext &C, return new (Mem) OpenACCVectorClause(BeginLoc, LParenLoc, IntExpr, EndLoc); } +OpenACCFinalizeClause *OpenACCFinalizeClause::Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation EndLoc) { + void *Mem = + C.Allocate(sizeof(OpenACCFinalizeClause), alignof(OpenACCFinalizeClause)); + return new (Mem) OpenACCFinalizeClause(BeginLoc, EndLoc); +} + +OpenACCIfPresentClause *OpenACCIfPresentClause::Create(const ASTContext &C, + SourceLocation BeginLoc, + SourceLocation EndLoc) { + void *Mem = C.Allocate(sizeof(OpenACCIfPresentClause), + alignof(OpenACCIfPresentClause)); + return new (Mem) OpenACCIfPresentClause(BeginLoc, EndLoc); +} + //===----------------------------------------------------------------------===// // OpenACC clauses printing methods //===----------------------------------------------------------------------===// @@ -530,6 +578,28 @@ void OpenACCClausePrinter::VisitAttachClause(const OpenACCAttachClause &C) { OS << ")"; } +void OpenACCClausePrinter::VisitDetachClause(const OpenACCDetachClause &C) { + OS << "detach("; + llvm::interleaveComma(C.getVarList(), OS, + [&](const Expr *E) { printExpr(E); }); + OS << ")"; +} + +void OpenACCClausePrinter::VisitDeleteClause(const OpenACCDeleteClause &C) { + OS << "delete("; + llvm::interleaveComma(C.getVarList(), OS, + [&](const Expr *E) { printExpr(E); }); + OS << ")"; +} + +void OpenACCClausePrinter::VisitUseDeviceClause( + const OpenACCUseDeviceClause &C) { + OS << "use_device("; + llvm::interleaveComma(C.getVarList(), OS, + [&](const Expr *E) { printExpr(E); }); + OS << ")"; +} + void OpenACCClausePrinter::VisitDevicePtrClause( const OpenACCDevicePtrClause &C) { OS << "deviceptr("; @@ -685,3 +755,12 @@ void OpenACCClausePrinter::VisitVectorClause(const OpenACCVectorClause &C) { OS << ")"; } } + +void OpenACCClausePrinter::VisitFinalizeClause(const OpenACCFinalizeClause &C) { + OS << "finalize"; +} + +void OpenACCClausePrinter::VisitIfPresentClause( + const OpenACCIfPresentClause &C) { + OS << "if_present"; +} diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp index b1b13b66a5e50..f749d3a705fc9 100644 --- a/clang/lib/AST/RecordLayoutBuilder.cpp +++ b/clang/lib/AST/RecordLayoutBuilder.cpp @@ -818,7 +818,7 @@ class ItaniumRecordLayoutBuilder { void setSize(CharUnits NewSize) { Size = Context.toBits(NewSize); } void setSize(uint64_t NewSize) { Size = NewSize; } - CharUnits getAligment() const { return Alignment; } + CharUnits getAlignment() const { return Alignment; } CharUnits getDataSize() const { assert(DataSize % Context.getCharWidth() == 0); diff --git a/clang/lib/AST/StmtOpenACC.cpp b/clang/lib/AST/StmtOpenACC.cpp index 23dd57d235813..fb73dfb3fa9de 100644 --- a/clang/lib/AST/StmtOpenACC.cpp +++ b/clang/lib/AST/StmtOpenACC.cpp @@ -110,3 +110,89 @@ OpenACCCombinedConstruct *OpenACCCombinedConstruct::Create( OpenACCCombinedConstruct(DK, BeginLoc, DirLoc, EndLoc, Clauses, Loop); return Inst; } + +OpenACCDataConstruct *OpenACCDataConstruct::CreateEmpty(const ASTContext &C, + unsigned NumClauses) { + void *Mem = + C.Allocate(OpenACCDataConstruct::totalSizeToAlloc( + NumClauses)); + auto *Inst = new (Mem) OpenACCDataConstruct(NumClauses); + return Inst; +} + +OpenACCDataConstruct * +OpenACCDataConstruct::Create(const ASTContext &C, SourceLocation Start, + SourceLocation DirectiveLoc, SourceLocation End, + ArrayRef Clauses, + Stmt *StructuredBlock) { + void *Mem = + C.Allocate(OpenACCDataConstruct::totalSizeToAlloc( + Clauses.size())); + auto *Inst = new (Mem) + OpenACCDataConstruct(Start, DirectiveLoc, End, Clauses, StructuredBlock); + return Inst; +} + +OpenACCEnterDataConstruct * +OpenACCEnterDataConstruct::CreateEmpty(const ASTContext &C, + unsigned NumClauses) { + void *Mem = C.Allocate( + OpenACCEnterDataConstruct::totalSizeToAlloc( + NumClauses)); + auto *Inst = new (Mem) OpenACCEnterDataConstruct(NumClauses); + return Inst; +} + +OpenACCEnterDataConstruct *OpenACCEnterDataConstruct::Create( + const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, + SourceLocation End, ArrayRef Clauses) { + void *Mem = C.Allocate( + OpenACCEnterDataConstruct::totalSizeToAlloc( + Clauses.size())); + auto *Inst = + new (Mem) OpenACCEnterDataConstruct(Start, DirectiveLoc, End, Clauses); + return Inst; +} + +OpenACCExitDataConstruct * +OpenACCExitDataConstruct::CreateEmpty(const ASTContext &C, + unsigned NumClauses) { + void *Mem = C.Allocate( + OpenACCExitDataConstruct::totalSizeToAlloc( + NumClauses)); + auto *Inst = new (Mem) OpenACCExitDataConstruct(NumClauses); + return Inst; +} + +OpenACCExitDataConstruct *OpenACCExitDataConstruct::Create( + const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, + SourceLocation End, ArrayRef Clauses) { + void *Mem = C.Allocate( + OpenACCExitDataConstruct::totalSizeToAlloc( + Clauses.size())); + auto *Inst = + new (Mem) OpenACCExitDataConstruct(Start, DirectiveLoc, End, Clauses); + return Inst; +} + +OpenACCHostDataConstruct * +OpenACCHostDataConstruct::CreateEmpty(const ASTContext &C, + unsigned NumClauses) { + void *Mem = C.Allocate( + OpenACCHostDataConstruct::totalSizeToAlloc( + NumClauses)); + auto *Inst = new (Mem) OpenACCHostDataConstruct(NumClauses); + return Inst; +} + +OpenACCHostDataConstruct *OpenACCHostDataConstruct::Create( + const ASTContext &C, SourceLocation Start, SourceLocation DirectiveLoc, + SourceLocation End, ArrayRef Clauses, + Stmt *StructuredBlock) { + void *Mem = C.Allocate( + OpenACCHostDataConstruct::totalSizeToAlloc( + Clauses.size())); + auto *Inst = new (Mem) OpenACCHostDataConstruct(Start, DirectiveLoc, End, + Clauses, StructuredBlock); + return Inst; +} diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp index 7507c9d14327a..488419add5e79 100644 --- a/clang/lib/AST/StmtPrinter.cpp +++ b/clang/lib/AST/StmtPrinter.cpp @@ -1193,6 +1193,51 @@ void StmtPrinter::VisitOpenACCCombinedConstruct(OpenACCCombinedConstruct *S) { PrintStmt(S->getLoop()); } +void StmtPrinter::VisitOpenACCDataConstruct(OpenACCDataConstruct *S) { + Indent() << "#pragma acc data"; + + if (!S->clauses().empty()) { + OS << ' '; + OpenACCClausePrinter Printer(OS, Policy); + Printer.VisitClauseList(S->clauses()); + } + OS << '\n'; + + PrintStmt(S->getStructuredBlock()); +} +void StmtPrinter::VisitOpenACCEnterDataConstruct(OpenACCEnterDataConstruct *S) { + Indent() << "#pragma acc enter data"; + + if (!S->clauses().empty()) { + OS << ' '; + OpenACCClausePrinter Printer(OS, Policy); + Printer.VisitClauseList(S->clauses()); + } + OS << '\n'; +} +void StmtPrinter::VisitOpenACCExitDataConstruct(OpenACCExitDataConstruct *S) { + Indent() << "#pragma acc exit data"; + + if (!S->clauses().empty()) { + OS << ' '; + OpenACCClausePrinter Printer(OS, Policy); + Printer.VisitClauseList(S->clauses()); + } + OS << '\n'; +} +void StmtPrinter::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) { + Indent() << "#pragma acc host_data"; + + if (!S->clauses().empty()) { + OS << ' '; + OpenACCClausePrinter Printer(OS, Policy); + Printer.VisitClauseList(S->clauses()); + } + OS << '\n'; + + PrintStmt(S->getStructuredBlock()); +} + //===----------------------------------------------------------------------===// // Expr printing methods. //===----------------------------------------------------------------------===// diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp index 3dfbef1cdb712..1fb238720ffb1 100644 --- a/clang/lib/AST/StmtProfile.cpp +++ b/clang/lib/AST/StmtProfile.cpp @@ -2515,6 +2515,11 @@ class OpenACCClauseProfiler } } + void VisitClauseWithVarList(const OpenACCClauseWithVarList &Clause) { + for (auto *E : Clause.getVarList()) + Profiler.VisitStmt(E); + } + #define VISIT_CLAUSE(CLAUSE_NAME) \ void Visit##CLAUSE_NAME##Clause(const OpenACC##CLAUSE_NAME##Clause &Clause); @@ -2532,25 +2537,21 @@ void OpenACCClauseProfiler::VisitIfClause(const OpenACCIfClause &Clause) { } void OpenACCClauseProfiler::VisitCopyClause(const OpenACCCopyClause &Clause) { - for (auto *E : Clause.getVarList()) - Profiler.VisitStmt(E); + VisitClauseWithVarList(Clause); } void OpenACCClauseProfiler::VisitCopyInClause( const OpenACCCopyInClause &Clause) { - for (auto *E : Clause.getVarList()) - Profiler.VisitStmt(E); + VisitClauseWithVarList(Clause); } void OpenACCClauseProfiler::VisitCopyOutClause( const OpenACCCopyOutClause &Clause) { - for (auto *E : Clause.getVarList()) - Profiler.VisitStmt(E); + VisitClauseWithVarList(Clause); } void OpenACCClauseProfiler::VisitCreateClause( const OpenACCCreateClause &Clause) { - for (auto *E : Clause.getVarList()) - Profiler.VisitStmt(E); + VisitClauseWithVarList(Clause); } void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) { @@ -2558,6 +2559,12 @@ void OpenACCClauseProfiler::VisitSelfClause(const OpenACCSelfClause &Clause) { Profiler.VisitStmt(Clause.getConditionExpr()); } +void OpenACCClauseProfiler::VisitFinalizeClause( + const OpenACCFinalizeClause &Clause) {} + +void OpenACCClauseProfiler::VisitIfPresentClause( + const OpenACCIfPresentClause &Clause) {} + void OpenACCClauseProfiler::VisitNumGangsClause( const OpenACCNumGangsClause &Clause) { for (auto *E : Clause.getIntExprs()) @@ -2583,38 +2590,47 @@ void OpenACCClauseProfiler::VisitCollapseClause( void OpenACCClauseProfiler::VisitPrivateClause( const OpenACCPrivateClause &Clause) { - for (auto *E : Clause.getVarList()) - Profiler.VisitStmt(E); + VisitClauseWithVarList(Clause); } void OpenACCClauseProfiler::VisitFirstPrivateClause( const OpenACCFirstPrivateClause &Clause) { - for (auto *E : Clause.getVarList()) - Profiler.VisitStmt(E); + VisitClauseWithVarList(Clause); } void OpenACCClauseProfiler::VisitAttachClause( const OpenACCAttachClause &Clause) { - for (auto *E : Clause.getVarList()) - Profiler.VisitStmt(E); + VisitClauseWithVarList(Clause); +} + +void OpenACCClauseProfiler::VisitDetachClause( + const OpenACCDetachClause &Clause) { + VisitClauseWithVarList(Clause); +} + +void OpenACCClauseProfiler::VisitDeleteClause( + const OpenACCDeleteClause &Clause) { + VisitClauseWithVarList(Clause); } void OpenACCClauseProfiler::VisitDevicePtrClause( const OpenACCDevicePtrClause &Clause) { - for (auto *E : Clause.getVarList()) - Profiler.VisitStmt(E); + VisitClauseWithVarList(Clause); } void OpenACCClauseProfiler::VisitNoCreateClause( const OpenACCNoCreateClause &Clause) { - for (auto *E : Clause.getVarList()) - Profiler.VisitStmt(E); + VisitClauseWithVarList(Clause); } void OpenACCClauseProfiler::VisitPresentClause( const OpenACCPresentClause &Clause) { - for (auto *E : Clause.getVarList()) - Profiler.VisitStmt(E); + VisitClauseWithVarList(Clause); +} + +void OpenACCClauseProfiler::VisitUseDeviceClause( + const OpenACCUseDeviceClause &Clause) { + VisitClauseWithVarList(Clause); } void OpenACCClauseProfiler::VisitVectorLengthClause( @@ -2666,8 +2682,7 @@ void OpenACCClauseProfiler::VisitGangClause(const OpenACCGangClause &Clause) { void OpenACCClauseProfiler::VisitReductionClause( const OpenACCReductionClause &Clause) { - for (auto *E : Clause.getVarList()) - Profiler.VisitStmt(E); + VisitClauseWithVarList(Clause); } } // namespace @@ -2697,6 +2712,37 @@ void StmtProfiler::VisitOpenACCCombinedConstruct( P.VisitOpenACCClauseList(S->clauses()); } +void StmtProfiler::VisitOpenACCDataConstruct(const OpenACCDataConstruct *S) { + VisitStmt(S); + + OpenACCClauseProfiler P{*this}; + P.VisitOpenACCClauseList(S->clauses()); +} + +void StmtProfiler::VisitOpenACCEnterDataConstruct( + const OpenACCEnterDataConstruct *S) { + VisitStmt(S); + + OpenACCClauseProfiler P{*this}; + P.VisitOpenACCClauseList(S->clauses()); +} + +void StmtProfiler::VisitOpenACCExitDataConstruct( + const OpenACCExitDataConstruct *S) { + VisitStmt(S); + + OpenACCClauseProfiler P{*this}; + P.VisitOpenACCClauseList(S->clauses()); +} + +void StmtProfiler::VisitOpenACCHostDataConstruct( + const OpenACCHostDataConstruct *S) { + VisitStmt(S); + + OpenACCClauseProfiler P{*this}; + P.VisitOpenACCClauseList(S->clauses()); +} + void StmtProfiler::VisitHLSLOutArgExpr(const HLSLOutArgExpr *S) { VisitStmt(S); } diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 2552c11a39532..b5af10dd00b77 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -409,8 +409,12 @@ void TextNodeDumper::Visit(const OpenACCClause *C) { case OpenACCClauseKind::PCopy: case OpenACCClauseKind::PresentOrCopy: case OpenACCClauseKind::If: + case OpenACCClauseKind::IfPresent: case OpenACCClauseKind::Independent: + case OpenACCClauseKind::Detach: + case OpenACCClauseKind::Delete: case OpenACCClauseKind::DevicePtr: + case OpenACCClauseKind::Finalize: case OpenACCClauseKind::FirstPrivate: case OpenACCClauseKind::NoCreate: case OpenACCClauseKind::NumGangs: @@ -421,6 +425,7 @@ void TextNodeDumper::Visit(const OpenACCClause *C) { case OpenACCClauseKind::Seq: case OpenACCClauseKind::Tile: case OpenACCClauseKind::Worker: + case OpenACCClauseKind::UseDevice: case OpenACCClauseKind::Vector: case OpenACCClauseKind::VectorLength: // The condition expression will be printed as a part of the 'children', @@ -2936,6 +2941,25 @@ void TextNodeDumper::VisitOpenACCCombinedConstruct( OS << " " << S->getDirectiveKind(); } +void TextNodeDumper::VisitOpenACCDataConstruct(const OpenACCDataConstruct *S) { + OS << " " << S->getDirectiveKind(); +} + +void TextNodeDumper::VisitOpenACCEnterDataConstruct( + const OpenACCEnterDataConstruct *S) { + OS << " " << S->getDirectiveKind(); +} + +void TextNodeDumper::VisitOpenACCExitDataConstruct( + const OpenACCExitDataConstruct *S) { + OS << " " << S->getDirectiveKind(); +} + +void TextNodeDumper::VisitOpenACCHostDataConstruct( + const OpenACCHostDataConstruct *S) { + OS << " " << S->getDirectiveKind(); +} + void TextNodeDumper::VisitEmbedExpr(const EmbedExpr *S) { AddChild("begin", [=] { OS << S->getStartingElementPos(); }); AddChild("number of elements", [=] { OS << S->getDataElementCount(); }); diff --git a/clang/lib/Analysis/PathDiagnostic.cpp b/clang/lib/Analysis/PathDiagnostic.cpp index 35472e705cfd8..5b14d138b6e28 100644 --- a/clang/lib/Analysis/PathDiagnostic.cpp +++ b/clang/lib/Analysis/PathDiagnostic.cpp @@ -484,10 +484,10 @@ SourceLocation PathDiagnosticLocation::getValidSourceLocation( // source code, so find an enclosing statement and use its location. if (!L.isValid()) { AnalysisDeclContext *ADC; - if (LAC.is()) - ADC = LAC.get()->getAnalysisDeclContext(); + if (auto *LC = dyn_cast(LAC)) + ADC = LC->getAnalysisDeclContext(); else - ADC = LAC.get(); + ADC = cast(LAC); ParentMap &PM = ADC->getParentMap(); diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp index cbcfefdc52549..050daee1168d4 100644 --- a/clang/lib/Analysis/ThreadSafetyCommon.cpp +++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp @@ -135,14 +135,30 @@ CapabilityExpr SExprBuilder::translateAttrExpr(const Expr *AttrExp, Ctx.NumArgs = CE->getNumArgs(); Ctx.FunArgs = CE->getArgs(); } else if (const auto *CE = dyn_cast(DeclExp)) { - Ctx.NumArgs = CE->getNumArgs(); - Ctx.FunArgs = CE->getArgs(); + // Calls to operators that are members need to be treated like member calls. + if (isa(CE) && isa(D)) { + Ctx.SelfArg = CE->getArg(0); + Ctx.SelfArrow = false; + Ctx.NumArgs = CE->getNumArgs() - 1; + Ctx.FunArgs = CE->getArgs() + 1; + } else { + Ctx.NumArgs = CE->getNumArgs(); + Ctx.FunArgs = CE->getArgs(); + } } else if (const auto *CE = dyn_cast(DeclExp)) { Ctx.SelfArg = nullptr; // Will be set below Ctx.NumArgs = CE->getNumArgs(); Ctx.FunArgs = CE->getArgs(); } + // Usually we want to substitute the self-argument for "this", but lambdas + // are an exception: "this" on or in a lambda call operator doesn't refer + // to the lambda, but to captured "this" in the context it was created in. + // This can happen for operator calls and member calls, so fix it up here. + if (const auto *CMD = dyn_cast(D)) + if (CMD->getParent()->isLambda()) + Ctx.SelfArg = nullptr; + if (Self) { assert(!Ctx.SelfArg && "Ambiguous self argument"); assert(isa(D) && "Self argument requires function"); @@ -326,7 +342,7 @@ til::SExpr *SExprBuilder::translateDeclRefExpr(const DeclRefExpr *DRE, } assert(I == 0); - return Ctx->FunArgs.get(); + return cast(Ctx->FunArgs); } } // Map the param back to the param of the original function declaration diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp index 40f529e52b44a..a9aff39df6474 100644 --- a/clang/lib/Analysis/UnsafeBufferUsage.cpp +++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp @@ -439,36 +439,25 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) { // already duplicated // - call both from Sema and from here - const auto *BaseDRE = - dyn_cast(Node.getBase()->IgnoreParenImpCasts()); - const auto *SLiteral = - dyn_cast(Node.getBase()->IgnoreParenImpCasts()); - uint64_t size; - - if (!BaseDRE && !SLiteral) + uint64_t limit; + if (const auto *CATy = + dyn_cast(Node.getBase() + ->IgnoreParenImpCasts() + ->getType() + ->getUnqualifiedDesugaredType())) { + limit = CATy->getLimitedSize(); + } else if (const auto *SLiteral = dyn_cast( + Node.getBase()->IgnoreParenImpCasts())) { + limit = SLiteral->getLength() + 1; + } else { return false; - - if (BaseDRE) { - if (!BaseDRE->getDecl()) - return false; - const auto *CATy = Finder->getASTContext().getAsConstantArrayType( - BaseDRE->getDecl()->getType()); - if (!CATy) { - return false; - } - size = CATy->getLimitedSize(); - } else if (SLiteral) { - size = SLiteral->getLength() + 1; } if (const auto *IdxLit = dyn_cast(Node.getIdx())) { const APInt ArrIdx = IdxLit->getValue(); - // FIXME: ArrIdx.isNegative() we could immediately emit an error as that's a - // bug - if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < size) + if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < limit) return true; } - return false; } diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp index 25a601573698e..8dd1888db2988 100644 --- a/clang/lib/Basic/Builtins.cpp +++ b/clang/lib/Basic/Builtins.cpp @@ -134,7 +134,7 @@ static bool builtinIsSupported(const Builtin::Info &BuiltinInfo, void Builtin::Context::initializeBuiltins(IdentifierTable &Table, const LangOptions& LangOpts) { // Step #1: mark all target-independent builtins with their ID's. - for (unsigned i = Builtin::NotBuiltin+1; i != Builtin::FirstTSBuiltin; ++i) + for (unsigned i = Builtin::NotBuiltin + 1; i != Builtin::FirstTSBuiltin; ++i) if (builtinIsSupported(BuiltinInfo[i], LangOpts)) { Table.get(BuiltinInfo[i].Name).setBuiltinID(i); } diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index 2d0e358116362..ae71758bc81e0 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -500,7 +500,8 @@ class WarningsSpecialCaseList : public llvm::SpecialCaseList { // the last section take precedence in such cases. void processSections(DiagnosticsEngine &Diags); - bool isDiagSuppressed(diag::kind DiagId, StringRef FilePath) const; + bool isDiagSuppressed(diag::kind DiagId, SourceLocation DiagLoc, + const SourceManager &SM) const; private: // Find the longest glob pattern that matches FilePath amongst @@ -573,13 +574,14 @@ void DiagnosticsEngine::setDiagSuppressionMapping(llvm::MemoryBuffer &Input) { WarningSuppressionList->processSections(*this); DiagSuppressionMapping = [WarningSuppressionList(std::move(WarningSuppressionList))]( - diag::kind DiagId, StringRef Path) { - return WarningSuppressionList->isDiagSuppressed(DiagId, Path); + diag::kind DiagId, SourceLocation DiagLoc, const SourceManager &SM) { + return WarningSuppressionList->isDiagSuppressed(DiagId, DiagLoc, SM); }; } bool WarningsSpecialCaseList::isDiagSuppressed(diag::kind DiagId, - StringRef FilePath) const { + SourceLocation DiagLoc, + const SourceManager &SM) const { const Section *DiagSection = DiagToSection.lookup(DiagId); if (!DiagSection) return false; @@ -589,7 +591,13 @@ bool WarningsSpecialCaseList::isDiagSuppressed(diag::kind DiagId, return false; const llvm::StringMap &CategoriesToMatchers = SrcEntriesIt->getValue(); - return globsMatches(CategoriesToMatchers, FilePath); + // We also use presumed locations here to improve reproducibility for + // preprocessed inputs. + if (PresumedLoc PLoc = SM.getPresumedLoc(DiagLoc); PLoc.isValid()) + return globsMatches( + CategoriesToMatchers, + llvm::sys::path::remove_leading_dotslash(PLoc.getFilename())); + return false; } bool WarningsSpecialCaseList::globsMatches( @@ -614,8 +622,10 @@ bool WarningsSpecialCaseList::globsMatches( } bool DiagnosticsEngine::isSuppressedViaMapping(diag::kind DiagId, - StringRef FilePath) const { - return DiagSuppressionMapping && DiagSuppressionMapping(DiagId, FilePath); + SourceLocation DiagLoc) const { + if (!hasSourceManager() || !DiagSuppressionMapping) + return false; + return DiagSuppressionMapping(DiagId, DiagLoc, getSourceManager()); } void DiagnosticsEngine::Report(const StoredDiagnostic &storedDiag) { diff --git a/clang/lib/Basic/DiagnosticIDs.cpp b/clang/lib/Basic/DiagnosticIDs.cpp index 44922aa7872db..d77f28c80b2eb 100644 --- a/clang/lib/Basic/DiagnosticIDs.cpp +++ b/clang/lib/Basic/DiagnosticIDs.cpp @@ -601,15 +601,8 @@ DiagnosticIDs::getDiagnosticSeverity(unsigned DiagID, SourceLocation Loc, return diag::Severity::Ignored; // Clang-diagnostics pragmas always take precedence over suppression mapping. - if (!Mapping.isPragma() && Diag.DiagSuppressionMapping) { - // We also use presumed locations here to improve reproducibility for - // preprocessed inputs. - if (PresumedLoc PLoc = SM.getPresumedLoc(Loc); - PLoc.isValid() && Diag.isSuppressedViaMapping( - DiagID, llvm::sys::path::remove_leading_dotslash( - PLoc.getFilename()))) - return diag::Severity::Ignored; - } + if (!Mapping.isPragma() && Diag.isSuppressedViaMapping(DiagID, Loc)) + return diag::Severity::Ignored; return Result; } diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index 2876c290a26b1..f0b6f7be6c84f 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -324,9 +324,9 @@ llvm::Expected FileManager::getFileRef(StringRef Filename, *SeenFileEntries .insert({Status.getName(), FileEntryRef::MapValue(*UFE, DirInfo)}) .first; - assert(Redirection.second->V.is() && + assert(isa(Redirection.second->V) && "filename redirected to a non-canonical filename?"); - assert(Redirection.second->V.get() == UFE && + assert(cast(Redirection.second->V) == UFE && "filename from getStatValue() refers to wrong file"); // Cache the redirection in the previously-inserted entry, still available @@ -398,9 +398,9 @@ FileEntryRef FileManager::getVirtualFileRef(StringRef Filename, off_t Size, {Filename, std::errc::no_such_file_or_directory}).first; if (NamedFileEnt.second) { FileEntryRef::MapValue Value = *NamedFileEnt.second; - if (LLVM_LIKELY(Value.V.is())) + if (LLVM_LIKELY(isa(Value.V))) return FileEntryRef(NamedFileEnt); - return FileEntryRef(*Value.V.get()); + return FileEntryRef(*cast(Value.V)); } // We've not seen this before, or the file is cached as non-existent. @@ -620,7 +620,7 @@ void FileManager::GetUniqueIDMapping( for (const auto &Entry : SeenFileEntries) { // Only return files that exist and are not redirected. - if (!Entry.getValue() || !Entry.getValue()->V.is()) + if (!Entry.getValue() || !isa(Entry.getValue()->V)) continue; FileEntryRef FE(Entry); // Add this file if it's the first one with the UID, or if its name is diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index 6e588ce63d813..44e982d3ee67f 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/AutoConvert.h" #include "llvm/Support/Capacity.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Endian.h" @@ -156,8 +157,11 @@ ContentCache::getBufferOrNone(DiagnosticsEngine &Diag, FileManager &FM, // Unless this is a named pipe (in which case we can handle a mismatch), // check that the file's size is the same as in the file entry (which may // have come from a stat cache). + // The buffer will always be larger than the file size on z/OS in the presence + // of characters outside the base character set. + assert(Buffer->getBufferSize() >= (size_t)ContentsEntry->getSize()); if (!ContentsEntry->isNamedPipe() && - Buffer->getBufferSize() != (size_t)ContentsEntry->getSize()) { + Buffer->getBufferSize() < (size_t)ContentsEntry->getSize()) { Diag.Report(Loc, diag::err_file_modified) << ContentsEntry->getName(); return std::nullopt; @@ -583,6 +587,17 @@ SourceManager::getOrCreateFileID(FileEntryRef SourceFile, FileCharacter); } +/// Helper function to determine if an input file requires conversion +bool needConversion(StringRef Filename) { +#ifdef __MVS__ + llvm::ErrorOr NeedConversion = + llvm::needzOSConversion(Filename.str().c_str()); + return NeedConversion && *NeedConversion; +#else + return false; +#endif +} + /// createFileID - Create a new FileID for the specified ContentCache and /// include position. This works regardless of whether the ContentCache /// corresponds to a file or some other input source. @@ -602,6 +617,20 @@ FileID SourceManager::createFileIDImpl(ContentCache &File, StringRef Filename, return FileID::get(LoadedID); } unsigned FileSize = File.getSize(); + bool NeedConversion = needConversion(Filename); + if (NeedConversion) { + // Buffer size may increase due to potential z/OS EBCDIC to UTF-8 + // conversion. + if (std::optional Buffer = + File.getBufferOrNone(Diag, getFileManager())) { + unsigned BufSize = Buffer->getBufferSize(); + if (BufSize > FileSize) { + if (File.ContentsEntry.has_value()) + File.ContentsEntry->updateFileEntryBufferSize(BufSize); + FileSize = BufSize; + } + } + } if (!(NextLocalOffset + FileSize + 1 > NextLocalOffset && NextLocalOffset + FileSize + 1 <= CurrentLoadedOffset)) { Diag.Report(IncludePos, diag::err_sloc_space_too_large); diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 0021d33c45d7c..706a391023b3a 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -726,6 +726,9 @@ std::unique_ptr AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::Linux: return std::make_unique>(Triple, Opts); + case llvm::Triple::FreeBSD: + return std::make_unique>(Triple, + Opts); default: return std::make_unique(Triple, Opts); } @@ -734,6 +737,9 @@ std::unique_ptr AllocateTarget(const llvm::Triple &Triple, case llvm::Triple::Linux: return std::make_unique>(Triple, Opts); + case llvm::Triple::FreeBSD: + return std::make_unique>(Triple, + Opts); default: return std::make_unique(Triple, Opts); } diff --git a/clang/lib/Basic/Targets/AArch64.cpp b/clang/lib/Basic/Targets/AArch64.cpp index b7d374c67f33e..53e102bbe4468 100644 --- a/clang/lib/Basic/Targets/AArch64.cpp +++ b/clang/lib/Basic/Targets/AArch64.cpp @@ -232,14 +232,23 @@ bool AArch64TargetInfo::validateTarget(DiagnosticsEngine &Diags) const { bool AArch64TargetInfo::validateGlobalRegisterVariable( StringRef RegName, unsigned RegSize, bool &HasSizeMismatch) const { - if ((RegName == "sp") || RegName.starts_with("x")) { + if (RegName == "sp") { HasSizeMismatch = RegSize != 64; return true; - } else if (RegName.starts_with("w")) { - HasSizeMismatch = RegSize != 32; - return true; } - return false; + if (RegName.starts_with("w")) + HasSizeMismatch = RegSize != 32; + else if (RegName.starts_with("x")) + HasSizeMismatch = RegSize != 64; + else + return false; + StringRef RegNum = RegName.drop_front(); + // Check if the register is reserved. See also + // AArch64TargetLowering::getRegisterByName(). + return RegNum == "0" || + (RegNum == "18" && + llvm::AArch64::isX18ReservedByDefault(getTriple())) || + getTargetOpts().FeatureMap.lookup(("reserve-x" + RegNum).str()); } bool AArch64TargetInfo::validateBranchProtection(StringRef Spec, StringRef, diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h index 75f53e96ce28f..cd9b3760ca587 100644 --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -231,6 +231,9 @@ class LLVM_LIBRARY_VISIBILITY FreeBSDTargetInfo : public OSTargetInfo { case llvm::Triple::riscv32: case llvm::Triple::riscv64: break; + case llvm::Triple::loongarch32: + case llvm::Triple::loongarch64: + break; } } }; @@ -473,7 +476,7 @@ class LLVM_LIBRARY_VISIBILITY PS3PPUTargetInfo : public OSTargetInfo { this->IntMaxType = TargetInfo::SignedLongLong; this->Int64Type = TargetInfo::SignedLongLong; this->SizeType = TargetInfo::UnsignedInt; - this->resetDataLayout("E-m:e-p:32:32-Fi64-i64:64-n32:64"); + this->resetDataLayout("E-m:e-p:32:32-Fi64-i64:64-i128:128-n32:64"); } }; diff --git a/clang/lib/Basic/Targets/PPC.h b/clang/lib/Basic/Targets/PPC.h index b0833d30550af..3cd0fcad17293 100644 --- a/clang/lib/Basic/Targets/PPC.h +++ b/clang/lib/Basic/Targets/PPC.h @@ -462,12 +462,12 @@ class LLVM_LIBRARY_VISIBILITY PPC64TargetInfo : public PPCTargetInfo { if (Triple.isOSAIX()) { // TODO: Set appropriate ABI for AIX platform. - DataLayout = "E-m:a-Fi64-i64:64-n32:64"; + DataLayout = "E-m:a-Fi64-i64:64-i128:128-n32:64"; LongDoubleWidth = 64; LongDoubleAlign = DoubleAlign = 32; LongDoubleFormat = &llvm::APFloat::IEEEdouble(); } else if ((Triple.getArch() == llvm::Triple::ppc64le)) { - DataLayout = "e-m:e-Fn32-i64:64-n32:64"; + DataLayout = "e-m:e-Fn32-i64:64-i128:128-n32:64"; ABI = "elfv2"; } else { DataLayout = "E-m:e"; @@ -478,7 +478,7 @@ class LLVM_LIBRARY_VISIBILITY PPC64TargetInfo : public PPCTargetInfo { ABI = "elfv1"; DataLayout += "-Fi64"; } - DataLayout += "-i64:64-n32:64"; + DataLayout += "-i64:64-i128:128-n32:64"; } if (Triple.isOSFreeBSD() || Triple.isOSOpenBSD() || Triple.isMusl()) { diff --git a/clang/lib/Basic/Targets/SystemZ.h b/clang/lib/Basic/Targets/SystemZ.h index ef9a07033a6e4..e6405f174f660 100644 --- a/clang/lib/Basic/Targets/SystemZ.h +++ b/clang/lib/Basic/Targets/SystemZ.h @@ -247,6 +247,8 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo { return RegNo < 4 ? 6 + RegNo : -1; } + bool hasSjLjLowering() const override { return true; } + std::pair hardwareInterferenceSizes() const override { return std::make_pair(256, 256); } diff --git a/clang/lib/Basic/Targets/WebAssembly.cpp b/clang/lib/Basic/Targets/WebAssembly.cpp index 85e550ad20d5e..7b0fd0c841ba2 100644 --- a/clang/lib/Basic/Targets/WebAssembly.cpp +++ b/clang/lib/Basic/Targets/WebAssembly.cpp @@ -31,7 +31,7 @@ static constexpr Builtin::Info BuiltinInfo[] = { }; static constexpr llvm::StringLiteral ValidCPUNames[] = { - {"mvp"}, {"bleeding-edge"}, {"generic"}, {"lime"}}; + {"mvp"}, {"bleeding-edge"}, {"generic"}, {"lime1"}}; StringRef WebAssemblyTargetInfo::getABI() const { return ABI; } diff --git a/clang/lib/Basic/Targets/WebAssembly.h b/clang/lib/Basic/Targets/WebAssembly.h index c92ed161a92a7..0a14da6a277b8 100644 --- a/clang/lib/Basic/Targets/WebAssembly.h +++ b/clang/lib/Basic/Targets/WebAssembly.h @@ -182,11 +182,12 @@ class LLVM_LIBRARY_VISIBILITY WebAssembly32TargetInfo const TargetOptions &Opts) : WebAssemblyTargetInfo(T, Opts) { if (T.isOSEmscripten()) - resetDataLayout("e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-" - "S128-ni:1:10:20"); - else resetDataLayout( - "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"); + "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-" + "S128-ni:1:10:20"); + else + resetDataLayout("e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-" + "S128-ni:1:10:20"); } protected: @@ -206,11 +207,12 @@ class LLVM_LIBRARY_VISIBILITY WebAssembly64TargetInfo PtrDiffType = SignedLong; IntPtrType = SignedLong; if (T.isOSEmscripten()) - resetDataLayout("e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-f128:64-n32:64-" - "S128-ni:1:10:20"); - else resetDataLayout( - "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20"); + "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-f128:64-n32:64-" + "S128-ni:1:10:20"); + else + resetDataLayout("e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-" + "S128-ni:1:10:20"); } protected: diff --git a/clang/lib/CIR/CodeGen/CIRGenBuilder.h b/clang/lib/CIR/CodeGen/CIRGenBuilder.h new file mode 100644 index 0000000000000..92115778518d4 --- /dev/null +++ b/clang/lib/CIR/CodeGen/CIRGenBuilder.h @@ -0,0 +1,28 @@ +//===----------------------------------------------------------------------===// +// +// 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_LIB_CIR_CODEGEN_CIRGENBUILDER_H +#define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENBUILDER_H + +#include "CIRGenTypeCache.h" + +#include "clang/CIR/Dialect/Builder/CIRBaseBuilder.h" + +namespace clang::CIRGen { + +class CIRGenBuilderTy : public cir::CIRBaseBuilderTy { + const CIRGenTypeCache &typeCache; + +public: + CIRGenBuilderTy(mlir::MLIRContext &mlirContext, const CIRGenTypeCache &tc) + : CIRBaseBuilderTy(mlirContext), typeCache(tc) {} +}; + +} // namespace clang::CIRGen + +#endif diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.cpp b/clang/lib/CIR/CodeGen/CIRGenModule.cpp index 5963d43bb9672..0db24c3b41d18 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenModule.cpp @@ -25,17 +25,31 @@ using namespace clang; using namespace clang::CIRGen; -CIRGenModule::CIRGenModule(mlir::MLIRContext &context, - clang::ASTContext &astctx, +CIRGenModule::CIRGenModule(mlir::MLIRContext &mlirContext, + clang::ASTContext &astContext, const clang::CodeGenOptions &cgo, DiagnosticsEngine &diags) - : builder(&context), astCtx(astctx), langOpts(astctx.getLangOpts()), - theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&context))}, - diags(diags), target(astCtx.getTargetInfo()) {} + : builder(mlirContext, *this), astContext(astContext), + langOpts(astContext.getLangOpts()), + theModule{mlir::ModuleOp::create(mlir::UnknownLoc::get(&mlirContext))}, + diags(diags), target(astContext.getTargetInfo()), genTypes(*this) { + + // Initialize cached types + SInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/true); + SInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/true); + SInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/true); + SInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/true); + SInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/true); + UInt8Ty = cir::IntType::get(&getMLIRContext(), 8, /*isSigned=*/false); + UInt16Ty = cir::IntType::get(&getMLIRContext(), 16, /*isSigned=*/false); + UInt32Ty = cir::IntType::get(&getMLIRContext(), 32, /*isSigned=*/false); + UInt64Ty = cir::IntType::get(&getMLIRContext(), 64, /*isSigned=*/false); + UInt128Ty = cir::IntType::get(&getMLIRContext(), 128, /*isSigned=*/false); +} mlir::Location CIRGenModule::getLoc(SourceLocation cLoc) { assert(cLoc.isValid() && "expected valid source location"); - const SourceManager &sm = astCtx.getSourceManager(); + const SourceManager &sm = astContext.getSourceManager(); PresumedLoc pLoc = sm.getPresumedLoc(cLoc); StringRef filename = pLoc.getFilename(); return mlir::FileLineColLoc::get(builder.getStringAttr(filename), @@ -67,7 +81,8 @@ void CIRGenModule::emitGlobal(clang::GlobalDecl gd) { return; } } else { - errorNYI(global->getSourceRange(), "global variable declaration"); + assert(cast(global)->isFileVarDecl() && + "Cannot emit local var decl as global"); } // TODO(CIR): Defer emitting some global definitions until later @@ -77,9 +92,27 @@ void CIRGenModule::emitGlobal(clang::GlobalDecl gd) { void CIRGenModule::emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op) { auto const *funcDecl = cast(gd.getDecl()); - auto funcOp = builder.create( - getLoc(funcDecl->getSourceRange()), funcDecl->getIdentifier()->getName()); - theModule.push_back(funcOp); + if (clang::IdentifierInfo *identifier = funcDecl->getIdentifier()) { + auto funcOp = builder.create( + getLoc(funcDecl->getSourceRange()), identifier->getName()); + theModule.push_back(funcOp); + } else { + errorNYI(funcDecl->getSourceRange().getBegin(), + "function definition with a non-identifier for a name"); + } +} + +void CIRGenModule::emitGlobalVarDefinition(const clang::VarDecl *vd, + bool isTentative) { + mlir::Type type = getTypes().convertType(vd->getType()); + if (clang::IdentifierInfo *identifier = vd->getIdentifier()) { + auto varOp = builder.create(getLoc(vd->getSourceRange()), + identifier->getName(), type); + theModule.push_back(varOp); + } else { + errorNYI(vd->getSourceRange().getBegin(), + "variable definition with a non-identifier for a name"); + } } void CIRGenModule::emitGlobalDefinition(clang::GlobalDecl gd, @@ -103,6 +136,9 @@ void CIRGenModule::emitGlobalDefinition(clang::GlobalDecl gd, return; } + if (const auto *vd = dyn_cast(decl)) + return emitGlobalVarDefinition(vd, !vd->hasDefinition()); + llvm_unreachable("Invalid argument to CIRGenModule::emitGlobalDefinition"); } @@ -126,13 +162,13 @@ void CIRGenModule::emitTopLevelDecl(Decl *decl) { emitGlobal(fd); break; } - } -} -DiagnosticBuilder CIRGenModule::errorNYI(llvm::StringRef feature) { - unsigned diagID = diags.getCustomDiagID( - DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0"); - return diags.Report(diagID) << feature; + case Decl::Var: { + auto *vd = cast(decl); + emitGlobal(vd); + break; + } + } } DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc, @@ -142,21 +178,7 @@ DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc, return diags.Report(loc, diagID) << feature; } -DiagnosticBuilder CIRGenModule::errorNYI(SourceLocation loc, - llvm::StringRef feature, - llvm::StringRef name) { - unsigned diagID = diags.getCustomDiagID( - DiagnosticsEngine::Error, "ClangIR code gen Not Yet Implemented: %0: %1"); - return diags.Report(loc, diagID) << feature << name; -} - DiagnosticBuilder CIRGenModule::errorNYI(SourceRange loc, llvm::StringRef feature) { return errorNYI(loc.getBegin(), feature) << loc; } - -DiagnosticBuilder CIRGenModule::errorNYI(SourceRange loc, - llvm::StringRef feature, - llvm::StringRef name) { - return errorNYI(loc.getBegin(), feature, name) << loc; -} diff --git a/clang/lib/CIR/CodeGen/CIRGenModule.h b/clang/lib/CIR/CodeGen/CIRGenModule.h index aaded92e6a633..1c7ed63773900 100644 --- a/clang/lib/CIR/CodeGen/CIRGenModule.h +++ b/clang/lib/CIR/CodeGen/CIRGenModule.h @@ -13,24 +13,24 @@ #ifndef LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H #define LLVM_CLANG_LIB_CIR_CODEGEN_CIRGENMODULE_H +#include "CIRGenBuilder.h" #include "CIRGenTypeCache.h" +#include "CIRGenTypes.h" #include "mlir/IR/Builders.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/MLIRContext.h" +#include "clang/Basic/SourceManager.h" #include "llvm/ADT/StringRef.h" namespace clang { class ASTContext; class CodeGenOptions; class Decl; -class DiagnosticBuilder; -class DiagnosticsEngine; class GlobalDecl; class LangOptions; -class SourceLocation; -class SourceRange; class TargetInfo; +class VarDecl; namespace CIRGen { @@ -41,19 +41,17 @@ class CIRGenModule : public CIRGenTypeCache { CIRGenModule &operator=(CIRGenModule &) = delete; public: - CIRGenModule(mlir::MLIRContext &context, clang::ASTContext &astctx, + CIRGenModule(mlir::MLIRContext &mlirContext, clang::ASTContext &astContext, const clang::CodeGenOptions &cgo, clang::DiagnosticsEngine &diags); ~CIRGenModule() = default; private: - // TODO(CIR) 'builder' will change to CIRGenBuilderTy once that type is - // defined - mlir::OpBuilder builder; + CIRGenBuilderTy builder; /// Hold Clang AST information. - clang::ASTContext &astCtx; + clang::ASTContext &astContext; const clang::LangOptions &langOpts; @@ -64,8 +62,14 @@ class CIRGenModule : public CIRGenTypeCache { const clang::TargetInfo ⌖ + CIRGenTypes genTypes; + public: mlir::ModuleOp getModule() const { return theModule; } + CIRGenBuilderTy &getBuilder() { return builder; } + clang::ASTContext &getASTContext() const { return astContext; } + CIRGenTypes &getTypes() { return genTypes; } + mlir::MLIRContext &getMLIRContext() { return *builder.getContext(); } /// Helpers to convert the presumed location of Clang's SourceLocation to an /// MLIR Location. @@ -81,13 +85,28 @@ class CIRGenModule : public CIRGenTypeCache { void emitGlobalDefinition(clang::GlobalDecl gd, mlir::Operation *op = nullptr); void emitGlobalFunctionDefinition(clang::GlobalDecl gd, mlir::Operation *op); + void emitGlobalVarDefinition(const clang::VarDecl *vd, + bool isTentative = false); /// Helpers to emit "not yet implemented" error diagnostics - DiagnosticBuilder errorNYI(llvm::StringRef); DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef); - DiagnosticBuilder errorNYI(SourceLocation, llvm::StringRef, llvm::StringRef); + + template + DiagnosticBuilder errorNYI(SourceLocation loc, llvm::StringRef feature, + const T &name) { + unsigned diagID = + diags.getCustomDiagID(DiagnosticsEngine::Error, + "ClangIR code gen Not Yet Implemented: %0: %1"); + return diags.Report(loc, diagID) << feature << name; + } + DiagnosticBuilder errorNYI(SourceRange, llvm::StringRef); - DiagnosticBuilder errorNYI(SourceRange, llvm::StringRef, llvm::StringRef); + + template + DiagnosticBuilder errorNYI(SourceRange loc, llvm::StringRef feature, + const T &name) { + return errorNYI(loc.getBegin(), feature, name) << loc; + } }; } // namespace CIRGen diff --git a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h index fde9a355f5241..a357663c33e0f 100644 --- a/clang/lib/CIR/CodeGen/CIRGenTypeCache.h +++ b/clang/lib/CIR/CodeGen/CIRGenTypeCache.h @@ -13,6 +13,8 @@ #ifndef LLVM_CLANG_LIB_CIR_CIRGENTYPECACHE_H #define LLVM_CLANG_LIB_CIR_CIRGENTYPECACHE_H +#include "clang/CIR/Dialect/IR/CIRTypes.h" + namespace clang::CIRGen { /// This structure provides a set of types that are commonly used @@ -20,6 +22,20 @@ namespace clang::CIRGen { /// constructor and then copied around into new CIRGenFunction's. struct CIRGenTypeCache { CIRGenTypeCache() = default; + + // ClangIR signed integral types of common sizes + cir::IntType SInt8Ty; + cir::IntType SInt16Ty; + cir::IntType SInt32Ty; + cir::IntType SInt64Ty; + cir::IntType SInt128Ty; + + // ClangIR unsigned integral type of common sizes + cir::IntType UInt8Ty; + cir::IntType UInt16Ty; + cir::IntType UInt32Ty; + cir::IntType UInt64Ty; + cir::IntType UInt128Ty; }; } // namespace clang::CIRGen diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.cpp b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp new file mode 100644 index 0000000000000..181af1898baff --- /dev/null +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.cpp @@ -0,0 +1,94 @@ +#include "CIRGenTypes.h" + +#include "CIRGenModule.h" + +#include "clang/AST/ASTContext.h" +#include "clang/AST/Type.h" + +using namespace clang; +using namespace clang::CIRGen; + +CIRGenTypes::CIRGenTypes(CIRGenModule &genModule) + : cgm(genModule), astContext(genModule.getASTContext()), + builder(cgm.getBuilder()) {} + +CIRGenTypes::~CIRGenTypes() {} + +mlir::MLIRContext &CIRGenTypes::getMLIRContext() const { + return *builder.getContext(); +} + +mlir::Type CIRGenTypes::convertType(QualType type) { + type = astContext.getCanonicalType(type); + const Type *ty = type.getTypePtr(); + + // Has the type already been processed? + TypeCacheTy::iterator tci = typeCache.find(ty); + if (tci != typeCache.end()) + return tci->second; + + // For types that haven't been implemented yet or are otherwise unsupported, + // report an error and return 'int'. + + mlir::Type resultType = nullptr; + switch (ty->getTypeClass()) { + case Type::Builtin: { + switch (cast(ty)->getKind()) { + // Signed integral types. + case BuiltinType::Char_S: + case BuiltinType::Int: + case BuiltinType::Int128: + case BuiltinType::Long: + case BuiltinType::LongLong: + case BuiltinType::SChar: + case BuiltinType::Short: + case BuiltinType::WChar_S: + resultType = + cir::IntType::get(&getMLIRContext(), astContext.getTypeSize(ty), + /*isSigned=*/true); + break; + // Unsigned integral types. + case BuiltinType::Char8: + case BuiltinType::Char16: + case BuiltinType::Char32: + case BuiltinType::Char_U: + case BuiltinType::UChar: + case BuiltinType::UInt: + case BuiltinType::UInt128: + case BuiltinType::ULong: + case BuiltinType::ULongLong: + case BuiltinType::UShort: + case BuiltinType::WChar_U: + resultType = + cir::IntType::get(&getMLIRContext(), astContext.getTypeSize(ty), + /*isSigned=*/false); + break; + default: + cgm.errorNYI(SourceLocation(), "processing of built-in type", type); + resultType = cgm.SInt32Ty; + break; + } + break; + } + case Type::BitInt: { + const auto *bitIntTy = cast(type); + if (bitIntTy->getNumBits() > cir::IntType::maxBitwidth()) { + cgm.errorNYI(SourceLocation(), "large _BitInt type", type); + resultType = cgm.SInt32Ty; + } else { + resultType = cir::IntType::get(&getMLIRContext(), bitIntTy->getNumBits(), + bitIntTy->isSigned()); + } + break; + } + default: + cgm.errorNYI(SourceLocation(), "processing of type", type); + resultType = cgm.SInt32Ty; + break; + } + + assert(resultType && "Type conversion not yet implemented"); + + typeCache[ty] = resultType; + return resultType; +} diff --git a/clang/lib/CIR/CodeGen/CIRGenTypes.h b/clang/lib/CIR/CodeGen/CIRGenTypes.h new file mode 100644 index 0000000000000..563d7759831fa --- /dev/null +++ b/clang/lib/CIR/CodeGen/CIRGenTypes.h @@ -0,0 +1,59 @@ +//===--- CIRGenTypes.h - Type translation for CIR CodeGen -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This is the code that handles AST -> CIR type lowering. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_CODEGEN_CODEGENTYPES_H +#define LLVM_CLANG_LIB_CODEGEN_CODEGENTYPES_H + +#include "clang/CIR/Dialect/IR/CIRTypes.h" + +#include "llvm/ADT/SmallPtrSet.h" + +namespace clang { +class ASTContext; +class QualType; +class Type; +} // namespace clang + +namespace mlir { +class Type; +} + +namespace clang::CIRGen { + +class CIRGenBuilderTy; +class CIRGenModule; + +/// This class organizes the cross-module state that is used while lowering +/// AST types to CIR types. +class CIRGenTypes { + CIRGenModule &cgm; + clang::ASTContext &astContext; + CIRGenBuilderTy &builder; + +public: + CIRGenTypes(CIRGenModule &cgm); + ~CIRGenTypes(); + + /// This map of clang::Type to mlir::Type (which includes CIR type) is a + /// cache of types that have already been processed. + using TypeCacheTy = llvm::DenseMap; + TypeCacheTy typeCache; + + mlir::MLIRContext &getMLIRContext() const; + + /// Convert a Clang type into a mlir::Type. + mlir::Type convertType(clang::QualType type); +}; + +} // namespace clang::CIRGen + +#endif diff --git a/clang/lib/CIR/CodeGen/CIRGenerator.cpp b/clang/lib/CIR/CodeGen/CIRGenerator.cpp index 8f3370c0041af..91070eda7d45a 100644 --- a/clang/lib/CIR/CodeGen/CIRGenerator.cpp +++ b/clang/lib/CIR/CodeGen/CIRGenerator.cpp @@ -29,15 +29,15 @@ CIRGenerator::CIRGenerator(clang::DiagnosticsEngine &diags, : diags(diags), fs(std::move(vfs)), codeGenOpts{cgo} {} CIRGenerator::~CIRGenerator() = default; -void CIRGenerator::Initialize(ASTContext &astCtx) { +void CIRGenerator::Initialize(ASTContext &astContext) { using namespace llvm; - this->astCtx = &astCtx; + this->astContext = &astContext; - mlirCtx = std::make_unique(); - mlirCtx->loadDialect(); - cgm = std::make_unique(*mlirCtx.get(), astCtx, - codeGenOpts, diags); + mlirContext = std::make_unique(); + mlirContext->loadDialect(); + cgm = std::make_unique( + *mlirContext.get(), astContext, codeGenOpts, diags); } mlir::ModuleOp CIRGenerator::getModule() const { return cgm->getModule(); } diff --git a/clang/lib/CIR/CodeGen/CMakeLists.txt b/clang/lib/CIR/CodeGen/CMakeLists.txt index 17a3aabfbd7f0..9ada31c11de95 100644 --- a/clang/lib/CIR/CodeGen/CMakeLists.txt +++ b/clang/lib/CIR/CodeGen/CMakeLists.txt @@ -9,6 +9,7 @@ get_property(dialect_libs GLOBAL PROPERTY MLIR_DIALECT_LIBS) add_clang_library(clangCIR CIRGenerator.cpp CIRGenModule.cpp + CIRGenTypes.cpp DEPENDS MLIRCIR diff --git a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp index f666e5ab4b999..dbdca1f840166 100644 --- a/clang/lib/CIR/Dialect/IR/CIRDialect.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRDialect.cpp @@ -32,6 +32,22 @@ void cir::CIRDialect::initialize() { >(); } +//===----------------------------------------------------------------------===// +// GlobalOp +//===----------------------------------------------------------------------===// + +// TODO(CIR): The properties of global variables that require verification +// haven't been implemented yet. +mlir::LogicalResult cir::GlobalOp::verify() { return success(); } + +void cir::GlobalOp::build(OpBuilder &odsBuilder, OperationState &odsState, + llvm::StringRef sym_name, mlir::Type sym_type) { + odsState.addAttribute(getSymNameAttrName(odsState.name), + odsBuilder.getStringAttr(sym_name)); + odsState.addAttribute(getSymTypeAttrName(odsState.name), + mlir::TypeAttr::get(sym_type)); +} + //===----------------------------------------------------------------------===// // FuncOp //===----------------------------------------------------------------------===// @@ -56,6 +72,8 @@ void cir::FuncOp::print(OpAsmPrinter &p) { p.printSymbolName(getSymName()); } +// TODO(CIR): The properties of functions that require verification haven't +// been implemented yet. mlir::LogicalResult cir::FuncOp::verify() { return success(); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp index 4eeb70f06f5f7..de38337057d3d 100644 --- a/clang/lib/CIR/Dialect/IR/CIRTypes.cpp +++ b/clang/lib/CIR/Dialect/IR/CIRTypes.cpp @@ -10,7 +10,18 @@ // //===----------------------------------------------------------------------===// +#include "clang/CIR/Dialect/IR/CIRTypes.h" + +#include "mlir/IR/DialectImplementation.h" #include "clang/CIR/Dialect/IR/CIRDialect.h" +#include "llvm/ADT/TypeSwitch.h" + +//===----------------------------------------------------------------------===// +// Get autogenerated stuff +//===----------------------------------------------------------------------===// + +#define GET_TYPEDEF_CLASSES +#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc" using namespace mlir; using namespace cir; @@ -20,12 +31,106 @@ using namespace cir; //===----------------------------------------------------------------------===// Type CIRDialect::parseType(DialectAsmParser &parser) const { - // No types yet to parse - return Type{}; + llvm::SMLoc typeLoc = parser.getCurrentLocation(); + llvm::StringRef mnemonic; + Type genType; + + // Try to parse as a tablegen'd type. + OptionalParseResult parseResult = + generatedTypeParser(parser, &mnemonic, genType); + if (parseResult.has_value()) + return genType; + + // TODO(CIR) Attempt to parse as a raw C++ type. + parser.emitError(typeLoc) << "unknown CIR type: " << mnemonic; + return Type(); } void CIRDialect::printType(Type type, DialectAsmPrinter &os) const { - // No types yet to print + // Try to print as a tablegen'd type. + if (generatedTypePrinter(type, os).succeeded()) + return; + + // TODO(CIR) Attempt to print as a raw C++ type. + llvm::report_fatal_error("printer is missing a handler for this type"); +} + +//===----------------------------------------------------------------------===// +// IntType Definitions +//===----------------------------------------------------------------------===// + +Type IntType::parse(mlir::AsmParser &parser) { + mlir::MLIRContext *context = parser.getBuilder().getContext(); + llvm::SMLoc loc = parser.getCurrentLocation(); + bool isSigned; + unsigned width; + + if (parser.parseLess()) + return {}; + + // Fetch integer sign. + llvm::StringRef sign; + if (parser.parseKeyword(&sign)) + return {}; + if (sign == "s") + isSigned = true; + else if (sign == "u") + isSigned = false; + else { + parser.emitError(loc, "expected 's' or 'u'"); + return {}; + } + + if (parser.parseComma()) + return {}; + + // Fetch integer size. + if (parser.parseInteger(width)) + return {}; + if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) { + parser.emitError(loc, "expected integer width to be from ") + << IntType::minBitwidth() << " up to " << IntType::maxBitwidth(); + return {}; + } + + if (parser.parseGreater()) + return {}; + + return IntType::get(context, width, isSigned); +} + +void IntType::print(mlir::AsmPrinter &printer) const { + char sign = isSigned() ? 's' : 'u'; + printer << '<' << sign << ", " << getWidth() << '>'; +} + +llvm::TypeSize +IntType::getTypeSizeInBits(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return llvm::TypeSize::getFixed(getWidth()); +} + +uint64_t IntType::getABIAlignment(const mlir::DataLayout &dataLayout, + mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +uint64_t +IntType::getPreferredAlignment(const ::mlir::DataLayout &dataLayout, + ::mlir::DataLayoutEntryListRef params) const { + return (uint64_t)(getWidth() / 8); +} + +mlir::LogicalResult +IntType::verify(llvm::function_ref emitError, + unsigned width, bool isSigned) { + if (width < IntType::minBitwidth() || width > IntType::maxBitwidth()) { + emitError() << "IntType only supports widths from " + << IntType::minBitwidth() << " up to " + << IntType::maxBitwidth(); + return mlir::failure(); + } + return mlir::success(); } //===----------------------------------------------------------------------===// @@ -33,5 +138,12 @@ void CIRDialect::printType(Type type, DialectAsmPrinter &os) const { //===----------------------------------------------------------------------===// void CIRDialect::registerTypes() { - // No types yet to register + // Register tablegen'd types. + addTypes< +#define GET_TYPEDEF_LIST +#include "clang/CIR/Dialect/IR/CIROpsTypes.cpp.inc" + >(); + + // Register raw C++ types. + // TODO(CIR) addTypes(); } diff --git a/clang/lib/CIR/Dialect/IR/CMakeLists.txt b/clang/lib/CIR/Dialect/IR/CMakeLists.txt index 75cee3f871130..7ddc4ce501907 100644 --- a/clang/lib/CIR/Dialect/IR/CMakeLists.txt +++ b/clang/lib/CIR/Dialect/IR/CMakeLists.txt @@ -8,4 +8,8 @@ add_clang_library(MLIRCIR LINK_LIBS PUBLIC MLIRIR + MLIRDLTIDialect + MLIRDataLayoutInterfaces + MLIRFuncDialect + clangAST ) diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index bf9b04f02e9f4..2ef098172c01f 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -738,6 +738,9 @@ static void addSanitizers(const Triple &TargetTriple, if (LangOpts.Sanitize.has(SanitizerKind::NumericalStability)) MPM.addPass(NumericalStabilitySanitizerPass()); + if (LangOpts.Sanitize.has(SanitizerKind::Realtime)) + MPM.addPass(RealtimeSanitizerPass()); + auto ASanPass = [&](SanitizerMask Mask, bool CompileKernel) { if (LangOpts.Sanitize.has(Mask)) { bool UseGlobalGC = asanUseGlobalsGC(TargetTriple, CodeGenOpts); @@ -789,13 +792,12 @@ static void addSanitizers(const Triple &TargetTriple, } if (LowerAllowCheckPass::IsRequested()) { - // We can optimize after inliner, and PGO profile matching. The hook below - // is called at the end `buildFunctionSimplificationPipeline`, which called - // from `buildInlinerPipeline`, which called after profile matching. - PB.registerScalarOptimizerLateEPCallback( - [](FunctionPassManager &FPM, OptimizationLevel Level) { - FPM.addPass(LowerAllowCheckPass()); - }); + // We want to call it after inline, which is about OptimizerEarlyEPCallback. + PB.registerOptimizerEarlyEPCallback([](ModulePassManager &MPM, + OptimizationLevel Level, + ThinOrFullLTOPhase Phase) { + MPM.addPass(createModuleToFunctionPassAdaptor(LowerAllowCheckPass())); + }); } } @@ -1024,13 +1026,6 @@ void EmitAssemblyHelper::RunOptimizationPipeline( FPM.addPass(BoundsCheckingPass()); }); - if (LangOpts.Sanitize.has(SanitizerKind::Realtime)) - PB.registerScalarOptimizerLateEPCallback( - [](FunctionPassManager &FPM, OptimizationLevel Level) { - RealtimeSanitizerOptions Opts; - FPM.addPass(RealtimeSanitizerPass(Opts)); - }); - // Don't add sanitizers if we are here from ThinLTO PostLink. That already // done on PreLink stage. if (!IsThinLTOPostLink) { diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 497a0b3952af8..4d4b7428abd50 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -4860,6 +4860,14 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID, // Buffer is a void**. Address Buf = EmitPointerWithAlignment(E->getArg(0)); + if (getTarget().getTriple().getArch() == llvm::Triple::systemz) { + // On this target, the back end fills in the context buffer completely. + // It doesn't really matter if the frontend stores to the buffer before + // calling setjmp, the back-end is going to overwrite them anyway. + Function *F = CGM.getIntrinsic(Intrinsic::eh_sjlj_setjmp); + return RValue::get(Builder.CreateCall(F, Buf.emitRawPointer(*this))); + } + // Store the frame pointer to the setjmp buffer. Value *FrameAddr = Builder.CreateCall( CGM.getIntrinsic(Intrinsic::frameaddress, AllocaInt8PtrTy), @@ -10201,6 +10209,8 @@ CodeGenFunction::getSVEType(const SVETypeFlags &TypeFlags) { case SVETypeFlags::EltTyInt64: return llvm::ScalableVectorType::get(Builder.getInt64Ty(), 2); + case SVETypeFlags::EltTyMFloat8: + return llvm::ScalableVectorType::get(Builder.getInt8Ty(), 16); case SVETypeFlags::EltTyFloat16: return llvm::ScalableVectorType::get(Builder.getHalfTy(), 8); case SVETypeFlags::EltTyBFloat16: @@ -10646,7 +10656,7 @@ Value *CodeGenFunction::EmitSMELd1St1(const SVETypeFlags &TypeFlags, NewOps.push_back(Ops[2]); llvm::Value *BasePtr = Ops[3]; - + llvm::Value *RealSlice = Ops[1]; // If the intrinsic contains the vnum parameter, multiply it with the vector // size in bytes. if (Ops.size() == 5) { @@ -10658,10 +10668,13 @@ Value *CodeGenFunction::EmitSMELd1St1(const SVETypeFlags &TypeFlags, Builder.CreateMul(StreamingVectorLengthCall, Ops[4], "mulvl"); // The type of the ptr parameter is void *, so use Int8Ty here. BasePtr = Builder.CreateGEP(Int8Ty, Ops[3], Mulvl); + RealSlice = Builder.CreateZExt(RealSlice, Int64Ty); + RealSlice = Builder.CreateAdd(RealSlice, Ops[4]); + RealSlice = Builder.CreateTrunc(RealSlice, Int32Ty); } NewOps.push_back(BasePtr); NewOps.push_back(Ops[0]); - NewOps.push_back(Ops[1]); + NewOps.push_back(RealSlice); Function *F = CGM.getIntrinsic(IntID); return Builder.CreateCall(F, NewOps); } @@ -10706,7 +10719,16 @@ Value *CodeGenFunction::EmitSVEDupX(Value *Scalar, llvm::Type *Ty) { cast(Ty)->getElementCount(), Scalar); } -Value *CodeGenFunction::EmitSVEDupX(Value* Scalar) { +Value *CodeGenFunction::EmitSVEDupX(Value *Scalar) { + if (auto *Ty = Scalar->getType(); Ty->isVectorTy()) { +#ifndef NDEBUG + auto *VecTy = cast(Ty); + ElementCount EC = VecTy->getElementCount(); + assert(EC.isScalar() && VecTy->getElementType() == Int8Ty && + "Only <1 x i8> expected"); +#endif + Scalar = Builder.CreateExtractElement(Scalar, uint64_t(0)); + } return EmitSVEDupX(Scalar, getSVEVectorForElementType(Scalar->getType())); } @@ -11252,6 +11274,10 @@ Value *CodeGenFunction::EmitAArch64SMEBuiltinExpr(unsigned BuiltinID, BuiltinID == SME::BI__builtin_sme_svstr_za) return EmitSMELdrStr(TypeFlags, Ops, Builtin->LLVMIntrinsic); + // Emit set FPMR for intrinsics that require it + if (TypeFlags.setsFPMR()) + Builder.CreateCall(CGM.getIntrinsic(Intrinsic::aarch64_set_fpmr), + Ops.pop_back_val()); // Handle builtins which require their multi-vector operands to be swapped swapCommutativeSMEOperands(BuiltinID, Ops); @@ -19410,6 +19436,15 @@ case Builtin::BI__builtin_hlsl_elementwise_isinf: { /*ReturnType=*/Op0->getType(), CGM.getHLSLRuntime().getStepIntrinsic(), ArrayRef{Op0, Op1}, nullptr, "hlsl.step"); } + case Builtin::BI__builtin_hlsl_wave_active_all_true: { + Value *Op = EmitScalarExpr(E->getArg(0)); + assert(Op->getType()->isIntegerTy(1) && + "Intrinsic WaveActiveAllTrue operand must be a bool"); + + Intrinsic::ID ID = CGM.getHLSLRuntime().getWaveActiveAllTrueIntrinsic(); + return EmitRuntimeCall( + Intrinsic::getOrInsertDeclaration(&CGM.getModule(), ID), {Op}); + } case Builtin::BI__builtin_hlsl_wave_active_any_true: { Value *Op = EmitScalarExpr(E->getArg(0)); assert(Op->getType()->isIntegerTy(1) && diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 7c8d962fa5a92..50b9dfbbab083 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -4379,7 +4379,7 @@ static void emitWritebackArg(CodeGenFunction &CGF, CallArgList &args, llvm::PHINode *phiToUse = CGF.Builder.CreatePHI(valueToUse->getType(), 2, "icr.to-use"); phiToUse->addIncoming(valueToUse, copyBB); - phiToUse->addIncoming(llvm::UndefValue::get(valueToUse->getType()), + phiToUse->addIncoming(llvm::PoisonValue::get(valueToUse->getType()), originBB); valueToUse = phiToUse; } @@ -4529,7 +4529,7 @@ void CodeGenFunction::EmitCallArgs( ArgTypes.assign(MD->param_type_begin() + ParamsToSkip, MD->param_type_end()); } else { - const auto *FPT = Prototype.P.get(); + const auto *FPT = cast(Prototype.P); IsVariadic = FPT->isVariadic(); ExplicitCC = FPT->getExtInfo().getCC(); ArgTypes.assign(FPT->param_type_begin() + ParamsToSkip, diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 5fccc9cbb37ec..79955f5571416 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1172,7 +1172,7 @@ llvm::Value *CodeGenFunction::GetCountedByFieldExprGEP( Indices.push_back(Builder.getInt32(0)); return Builder.CreateInBoundsGEP( ConvertType(QualType(RD->getTypeForDecl(), 0)), Res, - RecIndicesTy(llvm::reverse(Indices)), "..counted_by.gep"); + RecIndicesTy(llvm::reverse(Indices)), "counted_by.gep"); } /// This method is typically called in contexts where we can't generate @@ -1187,7 +1187,7 @@ llvm::Value *CodeGenFunction::EmitLoadOfCountedByField( const Expr *Base, const FieldDecl *FAMDecl, const FieldDecl *CountDecl) { if (llvm::Value *GEP = GetCountedByFieldExprGEP(Base, FAMDecl, CountDecl)) return Builder.CreateAlignedLoad(ConvertType(CountDecl->getType()), GEP, - getIntAlign(), "..counted_by.load"); + getIntAlign(), "counted_by.load"); return nullptr; } @@ -3581,6 +3581,12 @@ static void emitCheckHandlerCall(CodeGenFunction &CGF, llvm::AttributeList::FunctionIndex, B), /*Local=*/true); llvm::CallInst *HandlerCall = CGF.EmitNounwindRuntimeCall(Fn, FnArgs); + bool NoMerge = + ClSanitizeDebugDeoptimization || + !CGF.CGM.getCodeGenOpts().OptimizationLevel || + (CGF.CurCodeDecl && CGF.CurCodeDecl->hasAttr()); + if (NoMerge) + HandlerCall->addFnAttr(llvm::Attribute::NoMerge); if (!MayReturn) { HandlerCall->setDoesNotReturn(); CGF.Builder.CreateUnreachable(); diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 4ae8a2b22b1bb..4b71bd730ce12 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -2102,7 +2102,8 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) { Expr *InitVector = E->getInit(0); // Initialize from another scalable vector of the same type. - if (InitVector->getType() == E->getType()) + if (InitVector->getType().getCanonicalType() == + E->getType().getCanonicalType()) return Visit(InitVector); } @@ -2369,10 +2370,10 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) { ScalableDstTy->getElementCount().getKnownMinValue() / 8); } if (FixedSrcTy->getElementType() == ScalableDstTy->getElementType()) { - llvm::Value *UndefVec = llvm::UndefValue::get(ScalableDstTy); + llvm::Value *PoisonVec = llvm::PoisonValue::get(ScalableDstTy); llvm::Value *Zero = llvm::Constant::getNullValue(CGF.CGM.Int64Ty); llvm::Value *Result = Builder.CreateInsertVector( - ScalableDstTy, UndefVec, Src, Zero, "cast.scalable"); + ScalableDstTy, PoisonVec, Src, Zero, "cast.scalable"); if (Result->getType() != DstTy) Result = Builder.CreateBitCast(Result, DstTy); return Result; diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 2c293523fca8c..fb15b1993e74a 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -389,6 +389,11 @@ llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B, CGM.getIntrinsic(getThreadIdIntrinsic()); return buildVectorInput(B, ThreadIDIntrinsic, Ty); } + if (D.hasAttr()) { + llvm::Function *GroupThreadIDIntrinsic = + CGM.getIntrinsic(getGroupThreadIdIntrinsic()); + return buildVectorInput(B, GroupThreadIDIntrinsic, Ty); + } if (D.hasAttr()) { llvm::Function *GroupIDIntrinsic = CGM.getIntrinsic(Intrinsic::dx_group_id); return buildVectorInput(B, GroupIDIntrinsic, Ty); diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index bb120c8b5e9e6..85238ee34b447 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -86,11 +86,13 @@ class CGHLSLRuntime { GENERATE_HLSL_INTRINSIC_FUNCTION(Step, step) GENERATE_HLSL_INTRINSIC_FUNCTION(Radians, radians) GENERATE_HLSL_INTRINSIC_FUNCTION(ThreadId, thread_id) + GENERATE_HLSL_INTRINSIC_FUNCTION(GroupThreadId, thread_id_in_group) GENERATE_HLSL_INTRINSIC_FUNCTION(FDot, fdot) GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot) GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot) GENERATE_HLSL_INTRINSIC_FUNCTION(Dot4AddI8Packed, dot4add_i8packed) GENERATE_HLSL_INTRINSIC_FUNCTION(Dot4AddU8Packed, dot4add_u8packed) + GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAllTrue, wave_all) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAnyTrue, wave_any) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveCountBits, wave_active_countbits) GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane) diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 6a5860242035b..90809ef90858c 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -4085,7 +4085,7 @@ static void emitDependData(CodeGenFunction &CGF, QualType &KmpDependInfoTy, CGF.Builder.CreateConstGEP(DependenciesArray, *P), KmpDependInfoTy); } else { assert(E && "Expected a non-null expression"); - LValue &PosLVal = *Pos.get(); + LValue &PosLVal = *cast(Pos); llvm::Value *Idx = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc()); Base = CGF.MakeAddrLValue( CGF.Builder.CreateGEP(CGF, DependenciesArray, Idx), KmpDependInfoTy); @@ -4113,7 +4113,7 @@ static void emitDependData(CodeGenFunction &CGF, QualType &KmpDependInfoTy, if (unsigned *P = Pos.dyn_cast()) { ++(*P); } else { - LValue &PosLVal = *Pos.get(); + LValue &PosLVal = *cast(Pos); llvm::Value *Idx = CGF.EmitLoadOfScalar(PosLVal, E->getExprLoc()); Idx = CGF.Builder.CreateNUWAdd(Idx, llvm::ConstantInt::get(Idx->getType(), 1)); @@ -7770,7 +7770,7 @@ class MappableExprsHandler { if (const auto *Base = Data.dyn_cast()) getPlainLayout(Base, Layout, /*AsBase=*/true); else - Layout.push_back(Data.get()); + Layout.push_back(cast(Data)); } } @@ -8333,9 +8333,9 @@ class MappableExprsHandler { MapCombinedInfoTy &CombinedInfo, llvm::OpenMPIRBuilder &OMPBuilder, const llvm::DenseSet> &SkipVarSet = llvm::DenseSet>()) const { - assert(CurDir.is() && + assert(isa(CurDir) && "Expect a executable directive"); - const auto *CurExecDir = CurDir.get(); + const auto *CurExecDir = cast(CurDir); generateAllInfoForClauses(CurExecDir->clauses(), CombinedInfo, OMPBuilder, SkipVarSet); } @@ -8345,9 +8345,9 @@ class MappableExprsHandler { /// in \a CombinedInfo). void generateAllInfoForMapper(MapCombinedInfoTy &CombinedInfo, llvm::OpenMPIRBuilder &OMPBuilder) const { - assert(CurDir.is() && + assert(isa(CurDir) && "Expect a declare mapper directive"); - const auto *CurMapperDir = CurDir.get(); + const auto *CurMapperDir = cast(CurDir); generateAllInfoForClauses(CurMapperDir->clauses(), CombinedInfo, OMPBuilder); } @@ -8519,9 +8519,9 @@ class MappableExprsHandler { DeclComponentLists.emplace_back(MCL, OMPC_MAP_tofrom, Unknown, /*IsImpicit = */ true, nullptr, nullptr); - assert(CurDir.is() && + assert(isa(CurDir) && "Expect a executable directive"); - const auto *CurExecDir = CurDir.get(); + const auto *CurExecDir = cast(CurDir); bool HasMapBasePtr = false; bool HasMapArraySec = false; for (const auto *C : CurExecDir->getClausesOfKind()) { diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 698baf853507f..6c7a594fb10c4 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -458,6 +458,18 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef Attrs) { case Stmt::OpenACCCombinedConstructClass: EmitOpenACCCombinedConstruct(cast(*S)); break; + case Stmt::OpenACCDataConstructClass: + EmitOpenACCDataConstruct(cast(*S)); + break; + case Stmt::OpenACCEnterDataConstructClass: + EmitOpenACCEnterDataConstruct(cast(*S)); + break; + case Stmt::OpenACCExitDataConstructClass: + EmitOpenACCExitDataConstruct(cast(*S)); + break; + case Stmt::OpenACCHostDataConstructClass: + EmitOpenACCHostDataConstruct(cast(*S)); + break; } } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index eaea0d8a08ac0..092d55355a0a1 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -4094,6 +4094,30 @@ class CodeGenFunction : public CodeGenTypeCache { EmitStmt(S.getLoop()); } + void EmitOpenACCDataConstruct(const OpenACCDataConstruct &S) { + // TODO OpenACC: Implement this. It is currently implemented as a 'no-op', + // simply emitting its structured block, but in the future we will implement + // some sort of IR. + EmitStmt(S.getStructuredBlock()); + } + + void EmitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct &S) { + // TODO OpenACC: Implement this. It is currently implemented as a 'no-op', + // but in the future we will implement some sort of IR. + } + + void EmitOpenACCExitDataConstruct(const OpenACCExitDataConstruct &S) { + // TODO OpenACC: Implement this. It is currently implemented as a 'no-op', + // but in the future we will implement some sort of IR. + } + + void EmitOpenACCHostDataConstruct(const OpenACCHostDataConstruct &S) { + // TODO OpenACC: Implement this. It is currently implemented as a 'no-op', + // simply emitting its structured block, but in the future we will implement + // some sort of IR. + EmitStmt(S.getStructuredBlock()); + } + //===--------------------------------------------------------------------===// // LValue Expression Emission //===--------------------------------------------------------------------===// diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d3d5c0743a520..841fb1ced9a02 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1218,6 +1218,9 @@ void CodeGenModule::Release() { getModule().addModuleFlag(llvm::Module::Min, "ptrauth-elf-got", 1); if (getTriple().isOSLinux()) { + if (LangOpts.PointerAuthCalls) + getModule().addModuleFlag(llvm::Module::Min, "ptrauth-sign-personality", + 1); assert(getTriple().isOSBinFormatELF()); using namespace llvm::ELF; uint64_t PAuthABIVersion = diff --git a/clang/lib/CodeGen/ConstantInitBuilder.cpp b/clang/lib/CodeGen/ConstantInitBuilder.cpp index 549d5dd66b123..ddbf3ef743370 100644 --- a/clang/lib/CodeGen/ConstantInitBuilder.cpp +++ b/clang/lib/CodeGen/ConstantInitBuilder.cpp @@ -20,10 +20,10 @@ using namespace CodeGen; llvm::Type *ConstantInitFuture::getType() const { assert(Data && "dereferencing null future"); - if (Data.is()) { - return Data.get()->getType(); + if (const auto *C = dyn_cast(Data)) { + return C->getType(); } else { - return Data.get()->Buffer[0]->getType(); + return cast(Data)->Buffer[0]->getType(); } } @@ -37,10 +37,10 @@ void ConstantInitFuture::abandon() { void ConstantInitFuture::installInGlobal(llvm::GlobalVariable *GV) { assert(Data && "installing null future"); - if (Data.is()) { - GV->setInitializer(Data.get()); + if (auto *C = dyn_cast(Data)) { + GV->setInitializer(C); } else { - auto &builder = *Data.get(); + auto &builder = *cast(Data); assert(builder.Buffer.size() == 1); builder.setGlobalInitializer(GV, builder.Buffer[0]); builder.Buffer.clear(); diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 23b702c9b2ef2..261353150fdb7 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -1039,34 +1039,59 @@ bool Driver::readConfigFile(StringRef FileName, } // Try reading the given file. - SmallVector NewCfgArgs; - if (llvm::Error Err = ExpCtx.readConfigFile(FileName, NewCfgArgs)) { + SmallVector NewCfgFileArgs; + if (llvm::Error Err = ExpCtx.readConfigFile(FileName, NewCfgFileArgs)) { Diag(diag::err_drv_cannot_read_config_file) << FileName << toString(std::move(Err)); return true; } + // Populate head and tail lists. The tail list is used only when linking. + SmallVector NewCfgHeadArgs, NewCfgTailArgs; + for (const char *Opt : NewCfgFileArgs) { + // An $-prefixed option should go to the tail list. + if (Opt[0] == '$' && Opt[1]) + NewCfgTailArgs.push_back(Opt + 1); + else + NewCfgHeadArgs.push_back(Opt); + } + // Read options from config file. llvm::SmallString<128> CfgFileName(FileName); llvm::sys::path::native(CfgFileName); - bool ContainErrors; - auto NewOptions = std::make_unique( - ParseArgStrings(NewCfgArgs, /*UseDriverMode=*/true, ContainErrors)); + bool ContainErrors = false; + auto NewHeadOptions = std::make_unique( + ParseArgStrings(NewCfgHeadArgs, /*UseDriverMode=*/true, ContainErrors)); + if (ContainErrors) + return true; + auto NewTailOptions = std::make_unique( + ParseArgStrings(NewCfgTailArgs, /*UseDriverMode=*/true, ContainErrors)); if (ContainErrors) return true; // Claim all arguments that come from a configuration file so that the driver // does not warn on any that is unused. - for (Arg *A : *NewOptions) + for (Arg *A : *NewHeadOptions) + A->claim(); + for (Arg *A : *NewTailOptions) A->claim(); - if (!CfgOptions) - CfgOptions = std::move(NewOptions); + if (!CfgOptionsHead) + CfgOptionsHead = std::move(NewHeadOptions); else { // If this is a subsequent config file, append options to the previous one. - for (auto *Opt : *NewOptions) - appendOneArg(*CfgOptions, Opt); + for (auto *Opt : *NewHeadOptions) + appendOneArg(*CfgOptionsHead, Opt); } + + if (!CfgOptionsTail) + CfgOptionsTail = std::move(NewTailOptions); + else { + // If this is a subsequent config file, append options to the previous one. + for (auto *Opt : *NewTailOptions) + appendOneArg(*CfgOptionsTail, Opt); + } + ConfigFiles.push_back(std::string(CfgFileName)); return false; } @@ -1140,6 +1165,34 @@ bool Driver::loadConfigFiles() { return false; } +static bool findTripleConfigFile(llvm::cl::ExpansionContext &ExpCtx, + SmallString<128> &ConfigFilePath, + llvm::Triple Triple, std::string Suffix) { + // First, try the full unmodified triple. + if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath)) + return true; + + // Don't continue if we didn't find a parsable version in the triple. + VersionTuple OSVersion = Triple.getOSVersion(); + if (!OSVersion.getMinor().has_value()) + return false; + + std::string BaseOSName = Triple.getOSTypeName(Triple.getOS()).str(); + + // Next try strip the version to only include the major component. + // e.g. arm64-apple-darwin23.6.0 -> arm64-apple-darwin23 + if (OSVersion.getMajor() != 0) { + Triple.setOSName(BaseOSName + llvm::utostr(OSVersion.getMajor())); + if (ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath)) + return true; + } + + // Finally, try without any version suffix at all. + // e.g. arm64-apple-darwin23.6.0 -> arm64-apple-darwin + Triple.setOSName(BaseOSName); + return ExpCtx.findConfigFile(Triple.str() + Suffix, ConfigFilePath); +} + bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) { // Disable default config if CLANG_NO_DEFAULT_CONFIG is set to a non-empty // value. @@ -1151,7 +1204,7 @@ bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) { return false; std::string RealMode = getExecutableForDriverMode(Mode); - std::string Triple; + llvm::Triple Triple; // If name prefix is present, no --target= override was passed via CLOptions // and the name prefix is not a valid triple, force it for backwards @@ -1162,15 +1215,13 @@ bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) { llvm::Triple PrefixTriple{ClangNameParts.TargetPrefix}; if (PrefixTriple.getArch() == llvm::Triple::UnknownArch || PrefixTriple.isOSUnknown()) - Triple = PrefixTriple.str(); + Triple = PrefixTriple; } // Otherwise, use the real triple as used by the driver. - if (Triple.empty()) { - llvm::Triple RealTriple = - computeTargetTriple(*this, TargetTriple, *CLOptions); - Triple = RealTriple.str(); - assert(!Triple.empty()); + if (Triple.str().empty()) { + Triple = computeTargetTriple(*this, TargetTriple, *CLOptions); + assert(!Triple.str().empty()); } // Search for config files in the following order: @@ -1185,21 +1236,21 @@ bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) { // Try loading -.cfg, and return if we find a match. SmallString<128> CfgFilePath; - std::string CfgFileName = Triple + '-' + RealMode + ".cfg"; - if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) + if (findTripleConfigFile(ExpCtx, CfgFilePath, Triple, + "-" + RealMode + ".cfg")) return readConfigFile(CfgFilePath, ExpCtx); bool TryModeSuffix = !ClangNameParts.ModeSuffix.empty() && ClangNameParts.ModeSuffix != RealMode; if (TryModeSuffix) { - CfgFileName = Triple + '-' + ClangNameParts.ModeSuffix + ".cfg"; - if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) + if (findTripleConfigFile(ExpCtx, CfgFilePath, Triple, + "-" + ClangNameParts.ModeSuffix + ".cfg")) return readConfigFile(CfgFilePath, ExpCtx); } // Try loading .cfg, and return if loading failed. If a matching file // was not found, still proceed on to try .cfg. - CfgFileName = RealMode + ".cfg"; + std::string CfgFileName = RealMode + ".cfg"; if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) { if (readConfigFile(CfgFilePath, ExpCtx)) return true; @@ -1211,8 +1262,7 @@ bool Driver::loadDefaultConfigFiles(llvm::cl::ExpansionContext &ExpCtx) { } // Try loading .cfg and return if we find a match. - CfgFileName = Triple + ".cfg"; - if (ExpCtx.findConfigFile(CfgFileName, CfgFilePath)) + if (findTripleConfigFile(ExpCtx, CfgFilePath, Triple, ".cfg")) return readConfigFile(CfgFilePath, ExpCtx); // If we were unable to find a config file deduced from executable name, @@ -1243,13 +1293,14 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { // Try parsing configuration file. if (!ContainsError) ContainsError = loadConfigFiles(); - bool HasConfigFile = !ContainsError && (CfgOptions.get() != nullptr); + bool HasConfigFileHead = !ContainsError && CfgOptionsHead; + bool HasConfigFileTail = !ContainsError && CfgOptionsTail; // All arguments, from both config file and command line. - InputArgList Args = std::move(HasConfigFile ? std::move(*CfgOptions) - : std::move(*CLOptions)); + InputArgList Args = + HasConfigFileHead ? std::move(*CfgOptionsHead) : std::move(*CLOptions); - if (HasConfigFile) + if (HasConfigFileHead) for (auto *Opt : *CLOptions) if (!Opt->getOption().matches(options::OPT_config)) appendOneArg(Args, Opt); @@ -1540,6 +1591,15 @@ Compilation *Driver::BuildCompilation(ArrayRef ArgList) { // Construct the list of inputs. InputList Inputs; BuildInputs(C->getDefaultToolChain(), *TranslatedArgs, Inputs); + if (HasConfigFileTail && Inputs.size()) { + Arg *FinalPhaseArg; + if (getFinalPhase(*TranslatedArgs, &FinalPhaseArg) == phases::Link) { + DerivedArgList TranslatedLinkerIns(*CfgOptionsTail); + for (Arg *A : *CfgOptionsTail) + TranslatedLinkerIns.append(A); + BuildInputs(C->getDefaultToolChain(), TranslatedLinkerIns, Inputs); + } + } // Populate the tool chains for the offloading devices, if any. CreateOffloadingDeviceToolChains(*C, Inputs); @@ -4515,7 +4575,13 @@ Driver::getOffloadArchs(Compilation &C, const llvm::opt::DerivedArgList &Args, ToolChain::getOpenMPTriple(Arg->getValue(0)) == TC->getTriple()) { Arg->claim(); unsigned Index = Args.getBaseArgs().MakeIndex(Arg->getValue(1)); + unsigned Prev = Index; ExtractedArg = getOpts().ParseOneArg(Args, Index); + if (!ExtractedArg || Index > Prev + 1) { + TC->getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args) + << Arg->getAsString(Args); + continue; + } Arg = ExtractedArg.get(); } @@ -5774,15 +5840,10 @@ InputInfoList Driver::BuildJobsForActionNoCache( } } else { if (UnbundlingResults.empty()) - T->ConstructJob( - C, *JA, Result, InputInfos, - C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind()), - LinkingOutput); + T->ConstructJob(C, *JA, Result, InputInfos, Args, LinkingOutput); else - T->ConstructJobMultipleOutputs( - C, *JA, UnbundlingResults, InputInfos, - C.getArgsForToolChain(TC, BoundArch, JA->getOffloadingDeviceKind()), - LinkingOutput); + T->ConstructJobMultipleOutputs(C, *JA, UnbundlingResults, InputInfos, + Args, LinkingOutput); } return {Result}; } diff --git a/clang/lib/Driver/DriverOptions.cpp b/clang/lib/Driver/DriverOptions.cpp index 053e7f1c6404f..cde1f8989935b 100644 --- a/clang/lib/Driver/DriverOptions.cpp +++ b/clang/lib/Driver/DriverOptions.cpp @@ -14,24 +14,21 @@ using namespace clang::driver; using namespace clang::driver::options; using namespace llvm::opt; +#define OPTTABLE_STR_TABLE_CODE +#include "clang/Driver/Options.inc" +#undef OPTTABLE_STR_TABLE_CODE + #define OPTTABLE_VALUES_CODE #include "clang/Driver/Options.inc" #undef OPTTABLE_VALUES_CODE -#define PREFIX(NAME, VALUE) \ - static constexpr llvm::StringLiteral NAME##_init[] = VALUE; \ - static constexpr llvm::ArrayRef NAME( \ - NAME##_init, std::size(NAME##_init) - 1); +#define OPTTABLE_PREFIXES_TABLE_CODE #include "clang/Driver/Options.inc" -#undef PREFIX +#undef OPTTABLE_PREFIXES_TABLE_CODE -static constexpr const llvm::StringLiteral PrefixTable_init[] = -#define PREFIX_UNION(VALUES) VALUES +#define OPTTABLE_PREFIXES_UNION_CODE #include "clang/Driver/Options.inc" -#undef PREFIX_UNION - ; -static constexpr const llvm::ArrayRef - PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); +#undef OPTTABLE_PREFIXES_UNION_CODE static constexpr OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -43,7 +40,9 @@ namespace { class DriverOptTable : public PrecomputedOptTable { public: - DriverOptTable() : PrecomputedOptTable(InfoTable, PrefixTable) {} + DriverOptTable() + : PrecomputedOptTable(OptionStrTable, OptionPrefixesTable, InfoTable, + OptionPrefixesUnion) {} }; } diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp index 1abfe8fd92807..355dea5fad80b 100644 --- a/clang/lib/Driver/SanitizerArgs.cpp +++ b/clang/lib/Driver/SanitizerArgs.cpp @@ -247,39 +247,49 @@ static SanitizerMask setGroupBits(SanitizerMask Kinds) { return Kinds; } -static SanitizerMask parseSanitizeTrapArgs(const Driver &D, - const llvm::opt::ArgList &Args, - bool DiagnoseErrors) { - SanitizerMask TrapRemove; // During the loop below, the accumulated set of - // sanitizers disabled by the current sanitizer - // argument or any argument after it. - SanitizerMask TrappingKinds; - SanitizerMask TrappingSupportedWithGroups = setGroupBits(TrappingSupported); +// Computes the sanitizer mask based on the default plus opt-in (if supported) +// minus opt-out. +static SanitizerMask +parseSanitizeArgs(const Driver &D, const llvm::opt::ArgList &Args, + bool DiagnoseErrors, SanitizerMask Supported, + SanitizerMask Default, int OptInID, int OptOutID) { + SanitizerMask Remove; // During the loop below, the accumulated set of + // sanitizers disabled by the current sanitizer + // argument or any argument after it. + SanitizerMask Kinds; + SanitizerMask SupportedWithGroups = setGroupBits(Supported); for (const llvm::opt::Arg *Arg : llvm::reverse(Args)) { - if (Arg->getOption().matches(options::OPT_fsanitize_trap_EQ)) { + if (Arg->getOption().matches(OptInID)) { Arg->claim(); SanitizerMask Add = parseArgValues(D, Arg, true); - Add &= ~TrapRemove; - SanitizerMask InvalidValues = Add & ~TrappingSupportedWithGroups; + Add &= ~Remove; + SanitizerMask InvalidValues = Add & ~SupportedWithGroups; if (InvalidValues && DiagnoseErrors) { SanitizerSet S; S.Mask = InvalidValues; D.Diag(diag::err_drv_unsupported_option_argument) << Arg->getSpelling() << toString(S); } - TrappingKinds |= expandSanitizerGroups(Add) & ~TrapRemove; - } else if (Arg->getOption().matches(options::OPT_fno_sanitize_trap_EQ)) { + Kinds |= expandSanitizerGroups(Add) & ~Remove; + } else if (Arg->getOption().matches(OptOutID)) { Arg->claim(); - TrapRemove |= - expandSanitizerGroups(parseArgValues(D, Arg, DiagnoseErrors)); + Remove |= expandSanitizerGroups(parseArgValues(D, Arg, DiagnoseErrors)); } } - // Apply default trapping behavior. - TrappingKinds |= TrappingDefault & ~TrapRemove; + // Apply default behavior. + Kinds |= Default & ~Remove; - return TrappingKinds; + return Kinds; +} + +static SanitizerMask parseSanitizeTrapArgs(const Driver &D, + const llvm::opt::ArgList &Args, + bool DiagnoseErrors) { + return parseSanitizeArgs(D, Args, DiagnoseErrors, TrappingSupported, + TrappingDefault, options::OPT_fsanitize_trap_EQ, + options::OPT_fno_sanitize_trap_EQ); } bool SanitizerArgs::needsFuzzerInterceptors() const { @@ -418,8 +428,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, Add & NotAllowedWithExecuteOnly & ~DiagnosedKinds) { if (DiagnoseErrors) { std::string Desc = describeSanitizeArg(Arg, KindsToDiagnose); - D.Diag(diag::err_drv_argument_not_allowed_with) - << Desc << Triple.str(); + llvm::opt::Arg *A = Args.getLastArgNoClaim( + options::OPT_mexecute_only, options::OPT_mno_execute_only); + if (A && A->getOption().matches(options::OPT_mexecute_only)) + D.Diag(diag::err_drv_argument_not_allowed_with) + << Desc << A->getAsString(Args); + else + D.Diag(diag::err_drv_unsupported_opt_for_target) + << Desc << Triple.str(); } DiagnosedKinds |= KindsToDiagnose; } diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index f4e8353231de4..37249ca3c8c27 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -1593,8 +1593,10 @@ llvm::opt::DerivedArgList *ToolChain::TranslateOpenMPTargetArgs( Prev = Index; std::unique_ptr XOpenMPTargetArg(Opts.ParseOneArg(Args, Index)); if (!XOpenMPTargetArg || Index > Prev + 1) { - getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args) - << A->getAsString(Args); + if (!A->isClaimed()) { + getDriver().Diag(diag::err_drv_invalid_Xopenmp_target_with_args) + << A->getAsString(Args); + } continue; } if (XOpenMPTargetNoTriple && XOpenMPTargetArg && diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.cpp b/clang/lib/Driver/ToolChains/Arch/ARM.cpp index e6ee2317a160c..b8181ce6dc012 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.cpp +++ b/clang/lib/Driver/ToolChains/Arch/ARM.cpp @@ -52,6 +52,26 @@ bool arm::isARMAProfile(const llvm::Triple &Triple) { return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::A; } +/// Is the triple {arm,armeb,thumb,thumbeb}-none-none-{eabi,eabihf} ? +bool arm::isARMEABIBareMetal(const llvm::Triple &Triple) { + auto arch = Triple.getArch(); + if (arch != llvm::Triple::arm && arch != llvm::Triple::thumb && + arch != llvm::Triple::armeb && arch != llvm::Triple::thumbeb) + return false; + + if (Triple.getVendor() != llvm::Triple::UnknownVendor) + return false; + + if (Triple.getOS() != llvm::Triple::UnknownOS) + return false; + + if (Triple.getEnvironment() != llvm::Triple::EABI && + Triple.getEnvironment() != llvm::Triple::EABIHF) + return false; + + return true; +} + // Get Arch/CPU from args. void arm::getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch, llvm::StringRef &CPU, bool FromAs) { diff --git a/clang/lib/Driver/ToolChains/Arch/ARM.h b/clang/lib/Driver/ToolChains/Arch/ARM.h index fa62ac89e3a13..a23a8793a89e2 100644 --- a/clang/lib/Driver/ToolChains/Arch/ARM.h +++ b/clang/lib/Driver/ToolChains/Arch/ARM.h @@ -75,6 +75,7 @@ int getARMSubArchVersionNumber(const llvm::Triple &Triple); bool isARMMProfile(const llvm::Triple &Triple); bool isARMAProfile(const llvm::Triple &Triple); bool isARMBigEndian(const llvm::Triple &Triple, const llvm::opt::ArgList &Args); +bool isARMEABIBareMetal(const llvm::Triple &Triple); } // end namespace arm } // end namespace tools diff --git a/clang/lib/Driver/ToolChains/BareMetal.cpp b/clang/lib/Driver/ToolChains/BareMetal.cpp index f9a73f60973e4..eecaaa9a42930 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.cpp +++ b/clang/lib/Driver/ToolChains/BareMetal.cpp @@ -128,27 +128,6 @@ BareMetal::BareMetal(const Driver &D, const llvm::Triple &Triple, } } -/// Is the triple {arm,armeb,thumb,thumbeb}-none-none-{eabi,eabihf} ? -static bool isARMBareMetal(const llvm::Triple &Triple) { - if (Triple.getArch() != llvm::Triple::arm && - Triple.getArch() != llvm::Triple::thumb && - Triple.getArch() != llvm::Triple::armeb && - Triple.getArch() != llvm::Triple::thumbeb) - return false; - - if (Triple.getVendor() != llvm::Triple::UnknownVendor) - return false; - - if (Triple.getOS() != llvm::Triple::UnknownOS) - return false; - - if (Triple.getEnvironment() != llvm::Triple::EABI && - Triple.getEnvironment() != llvm::Triple::EABIHF) - return false; - - return true; -} - /// Is the triple {aarch64.aarch64_be}-none-elf? static bool isAArch64BareMetal(const llvm::Triple &Triple) { if (Triple.getArch() != llvm::Triple::aarch64 && @@ -267,7 +246,7 @@ void BareMetal::findMultilibs(const Driver &D, const llvm::Triple &Triple, } bool BareMetal::handlesTarget(const llvm::Triple &Triple) { - return isARMBareMetal(Triple) || isAArch64BareMetal(Triple) || + return arm::isARMEABIBareMetal(Triple) || isAArch64BareMetal(Triple) || isRISCVBareMetal(Triple) || isPPCBareMetal(Triple); } @@ -414,38 +393,6 @@ void BareMetal::AddClangCXXStdlibIncludeArgs(const ArgList &DriverArgs, } } -void BareMetal::AddCXXStdlibLibArgs(const ArgList &Args, - ArgStringList &CmdArgs) const { - switch (GetCXXStdlibType(Args)) { - case ToolChain::CST_Libcxx: - CmdArgs.push_back("-lc++"); - if (Args.hasArg(options::OPT_fexperimental_library)) - CmdArgs.push_back("-lc++experimental"); - CmdArgs.push_back("-lc++abi"); - break; - case ToolChain::CST_Libstdcxx: - CmdArgs.push_back("-lstdc++"); - CmdArgs.push_back("-lsupc++"); - break; - } - CmdArgs.push_back("-lunwind"); -} - -void BareMetal::AddLinkRuntimeLib(const ArgList &Args, - ArgStringList &CmdArgs) const { - ToolChain::RuntimeLibType RLT = GetRuntimeLibType(Args); - switch (RLT) { - case ToolChain::RLT_CompilerRT: { - CmdArgs.push_back(getCompilerRTArgString(Args, "builtins")); - return; - } - case ToolChain::RLT_Libgcc: - CmdArgs.push_back("-lgcc"); - return; - } - llvm_unreachable("Unhandled RuntimeLibType."); -} - void baremetal::StaticLibTool::ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, @@ -532,14 +479,21 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA, for (const auto &LibPath : TC.getLibraryPaths()) CmdArgs.push_back(Args.MakeArgString(llvm::Twine("-L", LibPath))); - if (TC.ShouldLinkCXXStdlib(Args)) + if (TC.ShouldLinkCXXStdlib(Args)) { + bool OnlyLibstdcxxStatic = Args.hasArg(options::OPT_static_libstdcxx) && + !Args.hasArg(options::OPT_static); + if (OnlyLibstdcxxStatic) + CmdArgs.push_back("-Bstatic"); TC.AddCXXStdlibLibArgs(Args, CmdArgs); + if (OnlyLibstdcxxStatic) + CmdArgs.push_back("-Bdynamic"); + CmdArgs.push_back("-lm"); + } if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { - CmdArgs.push_back("-lc"); - CmdArgs.push_back("-lm"); + AddRunTimeLibs(TC, D, CmdArgs, Args); - TC.AddLinkRuntimeLib(Args, CmdArgs); + CmdArgs.push_back("-lc"); } if (D.isUsingLTO()) { @@ -561,7 +515,7 @@ void baremetal::Linker::ConstructJob(Compilation &C, const JobAction &JA, // The R_ARM_TARGET2 relocation must be treated as R_ARM_REL32 on arm*-*-elf // and arm*-*-eabi (the default is R_ARM_GOT_PREL, used on arm*-*-linux and // arm*-*-*bsd). - if (isARMBareMetal(TC.getTriple())) + if (arm::isARMEABIBareMetal(TC.getTriple())) CmdArgs.push_back("--target2=rel"); CmdArgs.push_back("-o"); diff --git a/clang/lib/Driver/ToolChains/BareMetal.h b/clang/lib/Driver/ToolChains/BareMetal.h index b385c8cf76aab..483b5efab5e6e 100644 --- a/clang/lib/Driver/ToolChains/BareMetal.h +++ b/clang/lib/Driver/ToolChains/BareMetal.h @@ -67,10 +67,6 @@ class LLVM_LIBRARY_VISIBILITY BareMetal : public ToolChain { void AddClangCXXStdlibIncludeArgs( const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; - void AddCXXStdlibLibArgs(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const override; - void AddLinkRuntimeLib(const llvm::opt::ArgList &Args, - llvm::opt::ArgStringList &CmdArgs) const; std::string computeSysRoot() const override; SanitizerMask getSupportedSanitizers() const override; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 9c43500254324..776e710e5f33d 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -3773,11 +3773,13 @@ static void RenderSCPOptions(const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs) { const llvm::Triple &EffectiveTriple = TC.getEffectiveTriple(); - if (!EffectiveTriple.isOSFreeBSD() && !EffectiveTriple.isOSLinux()) + if (!EffectiveTriple.isOSFreeBSD() && !EffectiveTriple.isOSLinux() && + !EffectiveTriple.isOSFuchsia()) return; if (!EffectiveTriple.isX86() && !EffectiveTriple.isSystemZ() && - !EffectiveTriple.isPPC64() && !EffectiveTriple.isAArch64()) + !EffectiveTriple.isPPC64() && !EffectiveTriple.isAArch64() && + !EffectiveTriple.isRISCV()) return; Args.addOptInFlag(CmdArgs, options::OPT_fstack_clash_protection, @@ -4260,7 +4262,7 @@ static bool RenderModulesOptions(Compilation &C, const Driver &D, if (Args.hasArg(options::OPT_modules_reduced_bmi) && (Input.getType() == driver::types::TY_CXXModule || Input.getType() == driver::types::TY_PP_CXXModule)) { - CmdArgs.push_back("-fexperimental-modules-reduced-bmi"); + CmdArgs.push_back("-fmodules-reduced-bmi"); if (Args.hasArg(options::OPT_fmodule_output_EQ)) Args.AddLastArg(CmdArgs, options::OPT_fmodule_output_EQ); @@ -4270,7 +4272,7 @@ static bool RenderModulesOptions(Compilation &C, const Driver &D, getCXX20NamedModuleOutputPath(Args, Input.getBaseInput()))); } - // Noop if we see '-fexperimental-modules-reduced-bmi' with other translation + // Noop if we see '-fmodules-reduced-bmi' with other translation // units than module units. This is more user friendly to allow end uers to // enable this feature without asking for help from build systems. Args.ClaimAllArgs(options::OPT_modules_reduced_bmi); diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 8d977149e6248..ca675c117418c 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -19,6 +19,7 @@ #include "Arch/SystemZ.h" #include "Arch/VE.h" #include "Arch/X86.h" +#include "BareMetal.h" #include "HIPAMD.h" #include "Hexagon.h" #include "MSP430.h" @@ -151,6 +152,9 @@ static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args, } } + if (arm::isARMEABIBareMetal(Triple)) + return false; + return true; } @@ -490,6 +494,39 @@ void tools::AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, else A.renderAsInput(Args, CmdArgs); } + if (const Arg *A = Args.getLastArg(options::OPT_fveclib)) { + const llvm::Triple &Triple = TC.getTriple(); + StringRef V = A->getValue(); + if (V == "ArmPL" && (Triple.isOSLinux() || Triple.isOSDarwin())) { + // To support -fveclib=ArmPL we need to link against libamath. Some of the + // libamath functions depend on libm, at the same time, libamath exports + // its own implementation of some of the libm functions. These are faster + // and potentially less accurate implementations, hence we need to be + // careful what is being linked in. Since here we are interested only in + // the subset of libamath functions that is covered by the veclib + // mappings, we need to prioritize libm functions by putting -lm before + // -lamath (and then -lm again, to fulfill libamath requirements). + // + // Therefore we need to do the following: + // + // 1. On Linux, link only when actually needed. + // + // 2. Prefer libm functions over libamath. + // + // 3. Link against libm to resolve libamath dependencies. + // + if (Triple.isOSLinux()) { + CmdArgs.push_back(Args.MakeArgString("--push-state")); + CmdArgs.push_back(Args.MakeArgString("--as-needed")); + } + CmdArgs.push_back(Args.MakeArgString("-lm")); + CmdArgs.push_back(Args.MakeArgString("-lamath")); + CmdArgs.push_back(Args.MakeArgString("-lm")); + if (Triple.isOSLinux()) + CmdArgs.push_back(Args.MakeArgString("--pop-state")); + addArchSpecificRPath(TC, Args, CmdArgs); + } + } } void tools::addLinkerCompressDebugSectionsOption( diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 87380869f6fda..cdb6d21a0148b 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -430,13 +430,17 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args, // Give --sysroot= preference, over the Apple specific behavior to also use // --isysroot as the syslibroot. - StringRef sysroot = C.getSysRoot(); - if (sysroot != "") { + // We check `OPT__sysroot_EQ` directly instead of `getSysRoot` to make sure we + // prioritise command line arguments over configuration of `DEFAULT_SYSROOT`. + if (const Arg *A = Args.getLastArg(options::OPT__sysroot_EQ)) { CmdArgs.push_back("-syslibroot"); - CmdArgs.push_back(C.getArgs().MakeArgString(sysroot)); + CmdArgs.push_back(A->getValue()); } else if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { CmdArgs.push_back("-syslibroot"); CmdArgs.push_back(A->getValue()); + } else if (StringRef sysroot = C.getSysRoot(); sysroot != "") { + CmdArgs.push_back("-syslibroot"); + CmdArgs.push_back(C.getArgs().MakeArgString(sysroot)); } Args.AddLastArg(CmdArgs, options::OPT_twolevel__namespace); diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 48ce086de3b51..07b961b16dff4 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -150,7 +150,6 @@ void Flang::addCodegenOptions(const ArgList &Args, Args.addAllArgs(CmdArgs, {options::OPT_flang_experimental_hlfir, options::OPT_flang_deprecated_no_hlfir, - options::OPT_flang_experimental_integer_overflow, options::OPT_fno_ppc_native_vec_elem_order, options::OPT_fppc_native_vec_elem_order, options::OPT_do_concurrent_parallel_EQ}); @@ -216,6 +215,14 @@ void Flang::AddLoongArch64TargetArgs(const ArgList &Args, D.Diag(diag::err_drv_argument_not_allowed_with) << "-mabi" << V; } } + + if (const Arg *A = Args.getLastArg(options::OPT_mannotate_tablejump, + options::OPT_mno_annotate_tablejump)) { + if (A->getOption().matches(options::OPT_mannotate_tablejump)) { + CmdArgs.push_back("-mllvm"); + CmdArgs.push_back("-loongarch-annotate-tablejump"); + } + } } void Flang::AddPPCTargetArgs(const ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp index 3d744bc087f46..be44fc4fe1a84 100644 --- a/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -213,6 +213,14 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-m"); CmdArgs.push_back("elf64lriscv"); break; + case llvm::Triple::loongarch32: + CmdArgs.push_back("-m"); + CmdArgs.push_back("elf32loongarch"); + break; + case llvm::Triple::loongarch64: + CmdArgs.push_back("-m"); + CmdArgs.push_back("elf64loongarch"); + break; default: break; } @@ -223,6 +231,12 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("--no-relax"); } + if (Triple.isLoongArch64()) { + CmdArgs.push_back("-X"); + if (Args.hasArg(options::OPT_mno_relax)) + CmdArgs.push_back("--no-relax"); + } + if (Arg *A = Args.getLastArg(options::OPT_G)) { if (ToolChain.getTriple().isMIPS()) { StringRef v = A->getValue(); diff --git a/clang/lib/Driver/ToolChains/MSVC.cpp b/clang/lib/Driver/ToolChains/MSVC.cpp index 80799d1e715f0..752c2e2751ab6 100644 --- a/clang/lib/Driver/ToolChains/MSVC.cpp +++ b/clang/lib/Driver/ToolChains/MSVC.cpp @@ -84,6 +84,12 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA, else if (TC.getTriple().isWindowsArm64EC()) CmdArgs.push_back("-machine:arm64ec"); + if (const Arg *A = Args.getLastArg(options::OPT_fveclib)) { + StringRef V = A->getValue(); + if (V == "ArmPL") + CmdArgs.push_back(Args.MakeArgString("--dependent-lib=amath")); + } + if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) && !C.getDriver().IsCLMode() && !C.getDriver().IsFlangMode()) { CmdArgs.push_back("-defaultlib:libcmt"); diff --git a/clang/lib/Driver/XRayArgs.cpp b/clang/lib/Driver/XRayArgs.cpp index de5c38ebc3abb..f8c213334a2b4 100644 --- a/clang/lib/Driver/XRayArgs.cpp +++ b/clang/lib/Driver/XRayArgs.cpp @@ -51,6 +51,8 @@ XRayArgs::XRayArgs(const ToolChain &TC, const ArgList &Args) { case llvm::Triple::mips64: case llvm::Triple::mips64el: case llvm::Triple::systemz: + case llvm::Triple::riscv32: + case llvm::Triple::riscv64: break; default: D.Diag(diag::err_drv_unsupported_opt_for_target) diff --git a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp index c730c062b6a1d..e881d56258e5e 100644 --- a/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp +++ b/clang/lib/ExtractAPI/Serialization/SymbolGraphSerializer.cpp @@ -1067,9 +1067,8 @@ void SymbolGraphSerializer::serializeWithExtensionGraphs( for (auto &ExtensionSGF : Serializer.ExtendedModules) { if (auto ExtensionOS = - CreateOutputStream(ExtensionSGF.getKey() + "@" + API.ProductName)) - Serializer.serializeGraphToStream(*ExtensionOS, Options, - ExtensionSGF.getKey(), + CreateOutputStream(API.ProductName + "@" + ExtensionSGF.getKey())) + Serializer.serializeGraphToStream(*ExtensionOS, Options, API.ProductName, std::move(ExtensionSGF.getValue())); } } diff --git a/clang/lib/Format/CMakeLists.txt b/clang/lib/Format/CMakeLists.txt index b0f20f7c66937..9f4939824fdb8 100644 --- a/clang/lib/Format/CMakeLists.txt +++ b/clang/lib/Format/CMakeLists.txt @@ -41,28 +41,46 @@ file(GLOB_RECURSE files set(check_format_depends) set(i 0) -foreach (file IN LISTS files) - add_custom_command(OUTPUT clang-format-check-format${i} +foreach(file IN LISTS files) + add_custom_command(OUTPUT check_format_depend_${i} COMMAND clang-format ${file} | diff -u ${file} - VERBATIM - COMMENT "Checking format of ${file}..." + COMMENT "Checking format of ${file}" ) - list(APPEND check_format_depends clang-format-check-format${i}) - + list(APPEND check_format_depends check_format_depend_${i}) math(EXPR i ${i}+1) -endforeach () - +endforeach() add_custom_target(clang-format-check-format DEPENDS ${check_format_depends}) -set(style_options_depends ${CLANG_SOURCE_DIR}/docs/ClangFormatStyleOptions.rst) set(docs_tools_dir ${CLANG_SOURCE_DIR}/docs/tools) -add_custom_command(OUTPUT ${style_options_depends} - COMMAND ${Python3_EXECUTABLE} dump_format_style.py + +set(format_style_depend ${CMAKE_CURRENT_BINARY_DIR}/format_style_depend) +set(dump_style dump_format_style.py) +set(style_options_rst ${CLANG_SOURCE_DIR}/docs/ClangFormatStyleOptions.rst) +add_custom_command(OUTPUT ${format_style_depend} + COMMAND ${Python3_EXECUTABLE} ${dump_style} && touch ${format_style_depend} WORKING_DIRECTORY ${docs_tools_dir} + VERBATIM + COMMENT "Updating ${style_options_rst}" DEPENDS ${CLANG_SOURCE_DIR}/include/clang/Format/Format.h ${CLANG_SOURCE_DIR}/include/clang/Tooling/Inclusions/IncludeStyle.h + ${style_options_rst} ${docs_tools_dir}/plurals.txt - ${docs_tools_dir}/dump_format_style.py + ${docs_tools_dir}/${dump_style} + ) +add_custom_target(clang-format-style DEPENDS ${format_style_depend}) + +set(format_help_depend ${CMAKE_CURRENT_BINARY_DIR}/format_help_depend) +set(dump_help dump_format_help.py) +set(clang_format_rst ${CLANG_SOURCE_DIR}/docs/ClangFormat.rst) +add_custom_command(OUTPUT ${format_help_depend} + COMMAND ${Python3_EXECUTABLE} ${dump_help} -d ${CMAKE_BINARY_DIR}/bin && + touch ${format_help_depend} + WORKING_DIRECTORY ${docs_tools_dir} + VERBATIM + COMMENT "Updating ${clang_format_rst}" + DEPENDS clang-format + ${clang_format_rst} + ${docs_tools_dir}/${dump_help} ) -add_custom_target(clang-format-style-options DEPENDS ${style_options_depends}) -add_dependencies(clangFormat clang-format-style-options) +add_custom_target(clang-format-help DEPENDS ${format_help_depend}) diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp index bc5239209f3aa..05c86db55641f 100644 --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3901,6 +3901,11 @@ bool TokenAnnotator::mustBreakForReturnType(const AnnotatedLine &Line) const { } void TokenAnnotator::calculateFormattingInformation(AnnotatedLine &Line) const { + if (Line.Computed) + return; + + Line.Computed = true; + for (AnnotatedLine *ChildLine : Line.Children) calculateFormattingInformation(*ChildLine); @@ -6105,6 +6110,35 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, return false; } + // We can break before an r_brace if there was a break after the matching + // l_brace, which is tracked by BreakBeforeClosingBrace, or if we are in a + // block-indented initialization list. + if (Right.is(tok::r_brace)) { + return Right.MatchingParen && (Right.MatchingParen->is(BK_Block) || + (Right.isBlockIndentedInitRBrace(Style))); + } + + // We only break before r_paren if we're in a block indented context. + if (Right.is(tok::r_paren)) { + if (Style.AlignAfterOpenBracket != FormatStyle::BAS_BlockIndent || + !Right.MatchingParen) { + return false; + } + auto Next = Right.Next; + if (Next && Next->is(tok::r_paren)) + Next = Next->Next; + if (Next && Next->is(tok::l_paren)) + return false; + const FormatToken *Previous = Right.MatchingParen->Previous; + return !(Previous && (Previous->is(tok::kw_for) || Previous->isIf())); + } + + if (Left.isOneOf(tok::r_paren, TT_TrailingAnnotation) && + Right.is(TT_TrailingAnnotation) && + Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) { + return false; + } + if (Left.is(tok::at)) return false; if (Left.Tok.getObjCKeywordID() == tok::objc_interface) @@ -6260,34 +6294,6 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line, return false; } - // We only break before r_brace if there was a corresponding break before - // the l_brace, which is tracked by BreakBeforeClosingBrace. - if (Right.is(tok::r_brace)) { - return Right.MatchingParen && (Right.MatchingParen->is(BK_Block) || - (Right.isBlockIndentedInitRBrace(Style))); - } - - // We only break before r_paren if we're in a block indented context. - if (Right.is(tok::r_paren)) { - if (Style.AlignAfterOpenBracket != FormatStyle::BAS_BlockIndent || - !Right.MatchingParen) { - return false; - } - auto Next = Right.Next; - if (Next && Next->is(tok::r_paren)) - Next = Next->Next; - if (Next && Next->is(tok::l_paren)) - return false; - const FormatToken *Previous = Right.MatchingParen->Previous; - return !(Previous && (Previous->is(tok::kw_for) || Previous->isIf())); - } - - if (Left.isOneOf(tok::r_paren, TT_TrailingAnnotation) && - Right.is(TT_TrailingAnnotation) && - Style.AlignAfterOpenBracket == FormatStyle::BAS_BlockIndent) { - return false; - } - // Allow breaking after a trailing annotation, e.g. after a method // declaration. if (Left.is(TT_TrailingAnnotation)) { diff --git a/clang/lib/Format/TokenAnnotator.h b/clang/lib/Format/TokenAnnotator.h index 5a02030e5ba7f..9117ca3f9fb7b 100644 --- a/clang/lib/Format/TokenAnnotator.h +++ b/clang/lib/Format/TokenAnnotator.h @@ -182,6 +182,9 @@ class AnnotatedLine { /// \c True if this line contains a macro call for which an expansion exists. bool ContainsMacroCall = false; + /// \c True if calculateFormattingInformation() has been called on this line. + bool Computed = false; + /// \c True if this line should be formatted, i.e. intersects directly or /// indirectly with one of the input ranges. bool Affected; diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index c182aaf0876d1..de7e261b21d30 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -512,7 +512,7 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) { break; do { NextTok = Tokens->getNextToken(); - } while (NextTok->NewlinesBefore == 0 && NextTok->isNot(tok::eof)); + } while (!NextTok->HasUnescapedNewline && NextTok->isNot(tok::eof)); while (NextTok->is(tok::comment)) NextTok = Tokens->getNextToken(); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 98136b7a455d9..23906d5c06d38 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -277,6 +277,14 @@ CowCompilerInvocation::getMutPreprocessorOutputOpts() { using ArgumentConsumer = CompilerInvocation::ArgumentConsumer; +#define OPTTABLE_STR_TABLE_CODE +#include "clang/Driver/Options.inc" +#undef OPTTABLE_STR_TABLE_CODE + +static llvm::StringRef lookupStrInTable(unsigned Offset) { + return &OptionStrTable[Offset]; +} + #define SIMPLE_ENUM_VALUE_TABLE #include "clang/Driver/Options.inc" #undef SIMPLE_ENUM_VALUE_TABLE @@ -303,6 +311,11 @@ static std::optional normalizeSimpleNegativeFlag(OptSpecifier Opt, /// denormalizeSimpleFlags never looks at it. Avoid bloating compile-time with /// unnecessary template instantiations and just ignore it with a variadic /// argument. +static void denormalizeSimpleFlag(ArgumentConsumer Consumer, + unsigned SpellingOffset, Option::OptionClass, + unsigned, /*T*/...) { + Consumer(lookupStrInTable(SpellingOffset)); +} static void denormalizeSimpleFlag(ArgumentConsumer Consumer, const Twine &Spelling, Option::OptionClass, unsigned, /*T*/...) { @@ -343,10 +356,10 @@ static auto makeBooleanOptionNormalizer(bool Value, bool OtherValue, } static auto makeBooleanOptionDenormalizer(bool Value) { - return [Value](ArgumentConsumer Consumer, const Twine &Spelling, + return [Value](ArgumentConsumer Consumer, unsigned SpellingOffset, Option::OptionClass, unsigned, bool KeyPath) { if (KeyPath == Value) - Consumer(Spelling); + Consumer(lookupStrInTable(SpellingOffset)); }; } @@ -371,6 +384,14 @@ static void denormalizeStringImpl(ArgumentConsumer Consumer, } } +template +static void +denormalizeString(ArgumentConsumer Consumer, unsigned SpellingOffset, + Option::OptionClass OptClass, unsigned TableIndex, T Value) { + denormalizeStringImpl(Consumer, lookupStrInTable(SpellingOffset), OptClass, + TableIndex, Twine(Value)); +} + template static void denormalizeString(ArgumentConsumer Consumer, const Twine &Spelling, Option::OptionClass OptClass, unsigned TableIndex, @@ -417,14 +438,14 @@ static std::optional normalizeSimpleEnum(OptSpecifier Opt, } static void denormalizeSimpleEnumImpl(ArgumentConsumer Consumer, - const Twine &Spelling, + unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, unsigned Value) { assert(TableIndex < SimpleEnumValueTablesSize); const SimpleEnumValueTable &Table = SimpleEnumValueTables[TableIndex]; if (auto MaybeEnumVal = findValueTableByValue(Table, Value)) { - denormalizeString(Consumer, Spelling, OptClass, TableIndex, - MaybeEnumVal->Name); + denormalizeString(Consumer, lookupStrInTable(SpellingOffset), OptClass, + TableIndex, MaybeEnumVal->Name); } else { llvm_unreachable("The simple enum value was not correctly defined in " "the tablegen option description"); @@ -433,11 +454,11 @@ static void denormalizeSimpleEnumImpl(ArgumentConsumer Consumer, template static void denormalizeSimpleEnum(ArgumentConsumer Consumer, - const Twine &Spelling, + unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, T Value) { - return denormalizeSimpleEnumImpl(Consumer, Spelling, OptClass, TableIndex, - static_cast(Value)); + return denormalizeSimpleEnumImpl(Consumer, SpellingOffset, OptClass, + TableIndex, static_cast(Value)); } static std::optional normalizeString(OptSpecifier Opt, @@ -473,7 +494,7 @@ normalizeStringVector(OptSpecifier Opt, int, const ArgList &Args, } static void denormalizeStringVector(ArgumentConsumer Consumer, - const Twine &Spelling, + unsigned SpellingOffset, Option::OptionClass OptClass, unsigned TableIndex, const std::vector &Values) { @@ -487,15 +508,16 @@ static void denormalizeStringVector(ArgumentConsumer Consumer, CommaJoinedValue.append(Value); } } - denormalizeString(Consumer, Spelling, Option::OptionClass::JoinedClass, - TableIndex, CommaJoinedValue); + denormalizeString(Consumer, SpellingOffset, + Option::OptionClass::JoinedClass, TableIndex, + CommaJoinedValue); break; } case Option::JoinedClass: case Option::SeparateClass: case Option::JoinedOrSeparateClass: for (const std::string &Value : Values) - denormalizeString(Consumer, Spelling, OptClass, TableIndex, Value); + denormalizeString(Consumer, SpellingOffset, OptClass, TableIndex, Value); break; default: llvm_unreachable("Cannot denormalize an option with option class " @@ -532,10 +554,11 @@ static T extractMaskValue(T KeyPath) { } #define PARSE_OPTION_WITH_MARSHALLING( \ - ARGS, DIAGS, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, \ - FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \ - SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, \ - IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ + ARGS, DIAGS, PREFIX_TYPE, SPELLING_OFFSET, ID, KIND, GROUP, ALIAS, \ + ALIASARGS, FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, \ + METAVAR, VALUES, SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, \ + IMPLIED_CHECK, IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, \ + TABLE_INDEX) \ if ((VISIBILITY) & options::CC1Option) { \ KEYPATH = MERGER(KEYPATH, DEFAULT_VALUE); \ if (IMPLIED_CHECK) \ @@ -549,8 +572,8 @@ static T extractMaskValue(T KeyPath) { // Capture the extracted value as a lambda argument to avoid potential issues // with lifetime extension of the reference. #define GENERATE_OPTION_WITH_MARSHALLING( \ - CONSUMER, PREFIX_TYPE, SPELLING, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \ + CONSUMER, PREFIX_TYPE, SPELLING_OFFSET, ID, KIND, GROUP, ALIAS, ALIASARGS, \ + FLAGS, VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, VALUES, \ SHOULD_PARSE, ALWAYS_EMIT, KEYPATH, DEFAULT_VALUE, IMPLIED_CHECK, \ IMPLIED_VALUE, NORMALIZER, DENORMALIZER, MERGER, EXTRACTOR, TABLE_INDEX) \ if ((VISIBILITY) & options::CC1Option) { \ @@ -559,8 +582,8 @@ static T extractMaskValue(T KeyPath) { (Extracted != \ static_cast((IMPLIED_CHECK) ? (IMPLIED_VALUE) \ : (DEFAULT_VALUE)))) \ - DENORMALIZER(CONSUMER, SPELLING, Option::KIND##Class, TABLE_INDEX, \ - Extracted); \ + DENORMALIZER(CONSUMER, SPELLING_OFFSET, Option::KIND##Class, \ + TABLE_INDEX, Extracted); \ }(EXTRACTOR(KEYPATH)); \ } diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index 9b611bfcc9e63..e20feedb840b5 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -587,7 +587,7 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI, if (LangOpts.getSYCLVersion() == LangOptions::SYCL_2017) Builder.defineMacro("CL_SYCL_LANGUAGE_VERSION", "121"); else if (LangOpts.getSYCLVersion() == LangOptions::SYCL_2020) - Builder.defineMacro("SYCL_LANGUAGE_VERSION", "202001"); + Builder.defineMacro("SYCL_LANGUAGE_VERSION", "202012L"); } // Not "standard" per se, but available even with the -undef flag. diff --git a/clang/lib/Headers/avx10_2copyintrin.h b/clang/lib/Headers/avx10_2copyintrin.h index 7fc31190781d9..76b8f8ced540d 100644 --- a/clang/lib/Headers/avx10_2copyintrin.h +++ b/clang/lib/Headers/avx10_2copyintrin.h @@ -19,11 +19,43 @@ __attribute__((__always_inline__, __nodebug__, __target__("avx10.2-256"), \ __min_vector_width__(128))) +/// Constructs a 128-bit integer vector, setting the lower 32 bits to the +/// lower 32 bits of the parameter \a __A; the upper bits are zeoroed. +/// +/// \code{.operation} +/// result[31:0] := __A[31:0] +/// result[MAX:32] := 0 +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the VMOVD instruction. +/// +/// \param __A +/// A 128-bit integer vector. +/// \returns A 128-bit integer vector. The lower 32 bits are copied from the +/// parameter \a __A; the upper bits are zeroed. static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_move_epi32(__m128i __A) { return (__m128i)__builtin_shufflevector( (__v4si)__A, (__v4si)_mm_setzero_si128(), 0, 4, 4, 4); } +/// Constructs a 128-bit integer vector, setting the lower 16 bits to the +/// lower 16 bits of the parameter \a __A; the upper bits are zeoroed. +/// +/// \code{.operation} +/// result[15:0] := __A[15:0] +/// result[MAX:16] := 0 +/// \endcode +/// +/// \headerfile +/// +/// This intrinsic corresponds to the VMOVW instruction. +/// +/// \param __A +/// A 128-bit integer vector. +/// \returns A 128-bit integer vector. The lower 16 bits are copied from the +/// parameter \a __A; the upper bits are zeroed. static __inline__ __m128i __DEFAULT_FN_ATTRS128 _mm_move_epi16(__m128i __A) { return (__m128i)__builtin_shufflevector( (__v8hi)__A, (__v8hi)_mm_setzero_si128(), 0, 8, 8, 8, 8, 8, 8, 8); diff --git a/clang/lib/Headers/hlsl/hlsl_intrinsics.h b/clang/lib/Headers/hlsl/hlsl_intrinsics.h index 1126e13600f8a..b745997f1d5a2 100644 --- a/clang/lib/Headers/hlsl/hlsl_intrinsics.h +++ b/clang/lib/Headers/hlsl/hlsl_intrinsics.h @@ -2241,6 +2241,15 @@ float4 trunc(float4); // Wave* builtins //===----------------------------------------------------------------------===// +/// \brief Returns true if the expression is true in all active lanes in the +/// current wave. +/// +/// \param Val The boolean expression to evaluate. +/// \return True if the expression is true in all lanes. +_HLSL_AVAILABILITY(shadermodel, 6.0) +_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_all_true) +__attribute__((convergent)) bool WaveActiveAllTrue(bool Val); + /// \brief Returns true if the expression is true in any active lane in the /// current wave. /// diff --git a/clang/lib/Index/FileIndexRecord.cpp b/clang/lib/Index/FileIndexRecord.cpp index f3a5e6b63bbc2..449c33637eb7e 100644 --- a/clang/lib/Index/FileIndexRecord.cpp +++ b/clang/lib/Index/FileIndexRecord.cpp @@ -65,7 +65,7 @@ void FileIndexRecord::print(llvm::raw_ostream &OS, SourceManager &SM) const { OS << ' ' << ND->getDeclName(); } } else { - const auto *MI = DclInfo.DeclOrMacro.get(); + const auto *MI = cast(DclInfo.DeclOrMacro); SourceLocation Loc = SM.getFileLoc(MI->getDefinitionLoc()); PresumedLoc PLoc = SM.getPresumedLoc(Loc); OS << llvm::sys::path::filename(PLoc.getFilename()) << ':' diff --git a/clang/lib/Index/IndexDecl.cpp b/clang/lib/Index/IndexDecl.cpp index a7fa6c5e6898e..6c971bf0f381b 100644 --- a/clang/lib/Index/IndexDecl.cpp +++ b/clang/lib/Index/IndexDecl.cpp @@ -665,9 +665,9 @@ class IndexingDeclVisitor : public ConstDeclVisitor { ClassTemplatePartialSpecializationDecl *> Template = D->getSpecializedTemplateOrPartial(); const Decl *SpecializationOf = - Template.is() - ? (Decl *)Template.get() - : Template.get(); + isa(Template) + ? (Decl *)cast(Template) + : cast(Template); if (!D->isThisDeclarationADefinition()) IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D); IndexCtx.indexTagDecl( diff --git a/clang/lib/Interpreter/Interpreter.cpp b/clang/lib/Interpreter/Interpreter.cpp index 887b494ff98f1..fa4c1439c9261 100644 --- a/clang/lib/Interpreter/Interpreter.cpp +++ b/clang/lib/Interpreter/Interpreter.cpp @@ -200,7 +200,6 @@ IncrementalCompilerBuilder::CreateCpp() { #ifdef __EMSCRIPTEN__ Argv.push_back("-target"); Argv.push_back("wasm32-unknown-emscripten"); - Argv.push_back("-shared"); Argv.push_back("-fvisibility=default"); #endif Argv.insert(Argv.end(), UserArgs.begin(), UserArgs.end()); diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index e58c8bc72ae5b..72364500a48f9 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -527,7 +527,7 @@ bool Lexer::getRawToken(SourceLocation Loc, Token &Result, const char *StrData = Buffer.data()+LocInfo.second; - if (!IgnoreWhiteSpace && isWhitespace(StrData[0])) + if (!IgnoreWhiteSpace && isWhitespace(SkipEscapedNewLines(StrData)[0])) return true; // Create a lexer starting at the beginning of this token. diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 2ec66fe95708e..6c01af55ef3c4 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -722,8 +722,7 @@ void Parser::ParseLexedMemberInitializer(LateParsedMemberInitializer &MI) { ExprResult Init = ParseCXXMemberInitializer(MI.Field, /*IsFunction=*/false, EqualLoc); - Actions.ActOnFinishCXXInClassMemberInitializer(MI.Field, EqualLoc, - Init.get()); + Actions.ActOnFinishCXXInClassMemberInitializer(MI.Field, EqualLoc, Init); // The next token should be our artificial terminating EOF token. if (Tok.isNot(tok::eof)) { diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 736484ded8383..8dd72db8f5b4a 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1199,7 +1199,7 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind, // If the token is not annotated, then it might be an expression pack // indexing if (!TryAnnotateTypeOrScopeToken() && - Tok.is(tok::annot_pack_indexing_type)) + Tok.isOneOf(tok::annot_pack_indexing_type, tok::annot_cxxscope)) return ParseCastExpression(ParseKind, isAddressOfOperand, isTypeCast, isVectorLiteral, NotPrimaryExpression); } diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 03a58048e53a9..33a90e0cb8a42 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -238,7 +238,8 @@ bool Parser::ParseOptionalCXXScopeSpecifier( else if (!HasScopeSpecifier && Tok.is(tok::identifier) && GetLookAheadToken(1).is(tok::ellipsis) && - GetLookAheadToken(2).is(tok::l_square)) { + GetLookAheadToken(2).is(tok::l_square) && + !GetLookAheadToken(3).is(tok::r_square)) { SourceLocation Start = Tok.getLocation(); DeclSpec DS(AttrFactory); SourceLocation CCLoc; @@ -253,6 +254,19 @@ bool Parser::ParseOptionalCXXScopeSpecifier( if (Type.isNull()) return false; + // C++ [cpp23.dcl.dcl-2]: + // Previously, T...[n] would declare a pack of function parameters. + // T...[n] is now a pack-index-specifier. [...] Valid C++ 2023 code that + // declares a pack of parameters without specifying a declarator-id + // becomes ill-formed. + // + // However, we still treat it as a pack indexing type because the use case + // is fairly rare, to ensure semantic consistency given that we have + // backported this feature to pre-C++26 modes. + if (!Tok.is(tok::coloncolon) && !getLangOpts().CPlusPlus26 && + getCurScope()->isFunctionDeclarationScope()) + Diag(Start, diag::warn_pre_cxx26_ambiguous_pack_indexing_type) << Type; + if (!TryConsumeToken(tok::coloncolon, CCLoc)) { AnnotateExistingIndexedTypeNamePack(ParsedType::make(Type), Start, EndLoc); diff --git a/clang/lib/Parse/ParseHLSL.cpp b/clang/lib/Parse/ParseHLSL.cpp index 4de342b63ed80..443bf2b9ec626 100644 --- a/clang/lib/Parse/ParseHLSL.cpp +++ b/clang/lib/Parse/ParseHLSL.cpp @@ -280,6 +280,7 @@ void Parser::ParseHLSLAnnotations(ParsedAttributes &Attrs, case ParsedAttr::UnknownAttribute: Diag(Loc, diag::err_unknown_hlsl_semantic) << II; return; + case ParsedAttr::AT_HLSLSV_GroupThreadID: case ParsedAttr::AT_HLSLSV_GroupID: case ParsedAttr::AT_HLSLSV_GroupIndex: case ParsedAttr::AT_HLSLSV_DispatchThreadID: diff --git a/clang/lib/Parse/ParseOpenACC.cpp b/clang/lib/Parse/ParseOpenACC.cpp index b64c72904b19a..af175a465eb79 100644 --- a/clang/lib/Parse/ParseOpenACC.cpp +++ b/clang/lib/Parse/ParseOpenACC.cpp @@ -86,10 +86,14 @@ OpenACCClauseKind getOpenACCClauseKind(Token Tok) { if (Tok.is(tok::kw_if)) return OpenACCClauseKind::If; - // 'private' is also a keyword, make sure we pare it correctly. + // 'private' is also a keyword, make sure we parse it correctly. if (Tok.is(tok::kw_private)) return OpenACCClauseKind::Private; + // 'delete' is a keyword, make sure we parse it correctly. + if (Tok.is(tok::kw_delete)) + return OpenACCClauseKind::Delete; + if (!Tok.is(tok::identifier)) return OpenACCClauseKind::Invalid; @@ -567,6 +571,8 @@ void SkipUntilEndOfDirective(Parser &P) { bool doesDirectiveHaveAssociatedStmt(OpenACCDirectiveKind DirKind) { switch (DirKind) { default: + case OpenACCDirectiveKind::EnterData: + case OpenACCDirectiveKind::ExitData: return false; case OpenACCDirectiveKind::Parallel: case OpenACCDirectiveKind::Serial: @@ -575,6 +581,8 @@ bool doesDirectiveHaveAssociatedStmt(OpenACCDirectiveKind DirKind) { case OpenACCDirectiveKind::SerialLoop: case OpenACCDirectiveKind::KernelsLoop: case OpenACCDirectiveKind::Loop: + case OpenACCDirectiveKind::Data: + case OpenACCDirectiveKind::HostData: return true; } llvm_unreachable("Unhandled directive->assoc stmt"); @@ -592,6 +600,11 @@ unsigned getOpenACCScopeFlags(OpenACCDirectiveKind DirKind) { // so that we can diagnose trying to 'break'/'continue' inside of one. return Scope::BreakScope | Scope::ContinueScope | Scope::OpenACCComputeConstructScope; + case OpenACCDirectiveKind::Data: + case OpenACCDirectiveKind::EnterData: + case OpenACCDirectiveKind::ExitData: + case OpenACCDirectiveKind::HostData: + return 0; case OpenACCDirectiveKind::Invalid: llvm_unreachable("Shouldn't be creating a scope for an invalid construct"); default: @@ -985,17 +998,17 @@ Parser::OpenACCClauseParseResult Parser::ParseOpenACCClauseParams( // make sure we get the right differentiator. assert(DirKind == OpenACCDirectiveKind::Update); [[fallthrough]]; - case OpenACCClauseKind::Delete: - case OpenACCClauseKind::Detach: case OpenACCClauseKind::Device: case OpenACCClauseKind::DeviceResident: case OpenACCClauseKind::Host: case OpenACCClauseKind::Link: - case OpenACCClauseKind::UseDevice: ParseOpenACCVarList(ClauseKind); break; case OpenACCClauseKind::Attach: + case OpenACCClauseKind::Delete: + case OpenACCClauseKind::Detach: case OpenACCClauseKind::DevicePtr: + case OpenACCClauseKind::UseDevice: ParsedClause.setVarListDetails(ParseOpenACCVarList(ClauseKind), /*IsReadOnly=*/false, /*IsZero=*/false); break; @@ -1499,15 +1512,15 @@ StmtResult Parser::ParseOpenACCDirectiveStmt() { ParsingOpenACCDirectiveRAII DirScope(*this); OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective(); - if (getActions().OpenACC().ActOnStartStmtDirective(DirInfo.DirKind, - DirInfo.StartLoc)) + if (getActions().OpenACC().ActOnStartStmtDirective( + DirInfo.DirKind, DirInfo.StartLoc, DirInfo.Clauses)) return StmtError(); StmtResult AssocStmt; - SemaOpenACC::AssociatedStmtRAII AssocStmtRAII(getActions().OpenACC(), - DirInfo.DirKind, DirInfo.DirLoc, - {}, DirInfo.Clauses); if (doesDirectiveHaveAssociatedStmt(DirInfo.DirKind)) { + SemaOpenACC::AssociatedStmtRAII AssocStmtRAII( + getActions().OpenACC(), DirInfo.DirKind, DirInfo.DirLoc, {}, + DirInfo.Clauses); ParsingOpenACCDirectiveRAII DirScope(*this, /*Value=*/false); ParseScope ACCScope(this, getOpenACCScopeFlags(DirInfo.DirKind)); diff --git a/clang/lib/Parse/ParseOpenMP.cpp b/clang/lib/Parse/ParseOpenMP.cpp index b91928063169e..b4e973bc84a7b 100644 --- a/clang/lib/Parse/ParseOpenMP.cpp +++ b/clang/lib/Parse/ParseOpenMP.cpp @@ -3474,6 +3474,16 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind, Clause = ParseOpenMPOMPXAttributesClause(WrongDirective); break; case OMPC_ompx_bare: + if (DKind == llvm::omp::Directive::OMPD_target) { + // Flang splits the combined directives which requires OMPD_target to be + // marked as accepting the `ompx_bare` clause in `OMP.td`. Thus, we need + // to explicitly check whether this clause is applied to an `omp target` + // without `teams` and emit an error. + Diag(Tok, diag::err_omp_unexpected_clause) + << getOpenMPClauseName(CKind) << getOpenMPDirectiveName(DKind); + ErrorFound = true; + WrongDirective = true; + } if (WrongDirective) Diag(Tok, diag::note_ompx_bare_clause) << getOpenMPClauseName(CKind) << "target teams"; diff --git a/clang/lib/Sema/CheckExprLifetime.cpp b/clang/lib/Sema/CheckExprLifetime.cpp index 868081292bc32..843fdb4a65cd7 100644 --- a/clang/lib/Sema/CheckExprLifetime.cpp +++ b/clang/lib/Sema/CheckExprLifetime.cpp @@ -367,6 +367,8 @@ static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) { if (Callee->getReturnType()->isReferenceType()) { if (!Callee->getIdentifier()) { auto OO = Callee->getOverloadedOperator(); + if (!Callee->getParent()->hasAttr()) + return false; return OO == OverloadedOperatorKind::OO_Subscript || OO == OverloadedOperatorKind::OO_Star; } @@ -1152,6 +1154,86 @@ static bool pathOnlyHandlesGslPointer(const IndirectLocalPath &Path) { } return false; } +// Result of analyzing the Path for GSLPointer. +enum AnalysisResult { + // Path does not correspond to a GSLPointer. + NotGSLPointer, + + // A relevant case was identified. + Report, + // Stop the entire traversal. + Abandon, + // Skip this step and continue traversing inner AST nodes. + Skip, +}; +// Analyze cases where a GSLPointer is initialized or assigned from a +// temporary owner object. +static AnalysisResult analyzePathForGSLPointer(const IndirectLocalPath &Path, + Local L) { + if (!pathOnlyHandlesGslPointer(Path)) + return NotGSLPointer; + + // At this point, Path represents a series of operations involving a + // GSLPointer, either in the process of initialization or assignment. + + // Note: A LifetimeBoundCall can appear interleaved in this sequence. + // For example: + // const std::string& Ref(const std::string& a [[clang::lifetimebound]]); + // string_view abc = Ref(std::string()); + // The "Path" is [GSLPointerInit, LifetimeboundCall], where "L" is the + // temporary "std::string()" object. We need to check the return type of the + // function with the lifetimebound attribute. + if (Path.back().Kind == IndirectLocalPathEntry::LifetimeBoundCall) { + // The lifetimebound applies to the implicit object parameter of a method. + const FunctionDecl *FD = + llvm::dyn_cast_or_null(Path.back().D); + // The lifetimebound applies to a function parameter. + if (const auto *PD = llvm::dyn_cast(Path.back().D)) + FD = llvm::dyn_cast(PD->getDeclContext()); + + if (isa_and_present(FD)) { + // Constructor case: the parameter is annotated with lifetimebound + // e.g., GSLPointer(const S& s [[clang::lifetimebound]]) + // We still respect this case even the type S is not an owner. + return Report; + } + // Check the return type, e.g. + // const GSLOwner& func(const Foo& foo [[clang::lifetimebound]]) + // GSLPointer func(const Foo& foo [[clang::lifetimebound]]) + if (FD && + ((FD->getReturnType()->isReferenceType() && + isRecordWithAttr(FD->getReturnType()->getPointeeType())) || + isPointerLikeType(FD->getReturnType()))) + return Report; + + return Abandon; + } + + if (isa(L)) { + // We do not want to follow the references when returning a pointer + // originating from a local owner to avoid the following false positive: + // int &p = *localUniquePtr; + // someContainer.add(std::move(localUniquePtr)); + // return p; + if (!pathContainsInit(Path) && isRecordWithAttr(L->getType())) + return Report; + return Abandon; + } + + // The GSLPointer is from a temporary object. + auto *MTE = dyn_cast(L); + + bool IsGslPtrValueFromGslTempOwner = + MTE && !MTE->getExtendingDecl() && + isRecordWithAttr(MTE->getType()); + // Skipping a chain of initializing gsl::Pointer annotated objects. + // We are looking only for the final source to find out if it was + // a local or temporary owner or the address of a local + // variable/param. + if (!IsGslPtrValueFromGslTempOwner) + return Skip; + return Report; +} static bool isAssignmentOperatorLifetimeBound(CXXMethodDecl *CMD) { return CMD && isNormalAssignmentOperator(CMD) && CMD->param_size() == 1 && @@ -1189,27 +1271,17 @@ checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *InitEntity, auto *MTE = dyn_cast(L); - bool IsGslPtrValueFromGslTempOwner = false; - if (pathOnlyHandlesGslPointer(Path)) { - if (isa(L)) { - // We do not want to follow the references when returning a pointer - // originating from a local owner to avoid the following false positive: - // int &p = *localUniquePtr; - // someContainer.add(std::move(localUniquePtr)); - // return p; - if (pathContainsInit(Path) || - !isRecordWithAttr(L->getType())) - return false; - } else { - IsGslPtrValueFromGslTempOwner = - MTE && !MTE->getExtendingDecl() && - isRecordWithAttr(MTE->getType()); - // Skipping a chain of initializing gsl::Pointer annotated objects. - // We are looking only for the final source to find out if it was - // a local or temporary owner or the address of a local variable/param. - if (!IsGslPtrValueFromGslTempOwner) - return true; - } + bool IsGslPtrValueFromGslTempOwner = true; + switch (analyzePathForGSLPointer(Path, L)) { + case Abandon: + return false; + case Skip: + return true; + case NotGSLPointer: + IsGslPtrValueFromGslTempOwner = false; + LLVM_FALLTHROUGH; + case Report: + break; } switch (LK) { diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index ee237ffc4d2b9..47644680b720b 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -1343,8 +1343,7 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { S.getLocForEndOfToken(getTypeSpecComplexLoc()), " double"); TypeSpecType = TST_double; // _Complex -> _Complex double. - } else if (TypeSpecType == TST_int || TypeSpecType == TST_char || - TypeSpecType == TST_bitint) { + } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) { // Note that this intentionally doesn't include _Complex _Bool. if (!S.getLangOpts().CPlusPlus) S.Diag(TSTLoc, diag::ext_integer_complex); diff --git a/clang/lib/Sema/HLSLExternalSemaSource.cpp b/clang/lib/Sema/HLSLExternalSemaSource.cpp index f849e841de190..09fced1115687 100644 --- a/clang/lib/Sema/HLSLExternalSemaSource.cpp +++ b/clang/lib/Sema/HLSLExternalSemaSource.cpp @@ -35,14 +35,17 @@ namespace { struct TemplateParameterListBuilder; -struct BuiltinTypeDeclBuilder { - Sema &SemaRef; - CXXRecordDecl *Record = nullptr; +class BuiltinTypeDeclBuilder { ClassTemplateDecl *Template = nullptr; ClassTemplateDecl *PrevTemplate = nullptr; NamespaceDecl *HLSLNamespace = nullptr; llvm::StringMap Fields; +public: + Sema &SemaRef; + CXXRecordDecl *Record = nullptr; + friend struct TemplateParameterListBuilder; + BuiltinTypeDeclBuilder(Sema &SemaRef, CXXRecordDecl *R) : SemaRef(SemaRef), Record(R) { Record->startDefinition(); @@ -51,7 +54,7 @@ struct BuiltinTypeDeclBuilder { BuiltinTypeDeclBuilder(Sema &SemaRef, NamespaceDecl *Namespace, StringRef Name) - : SemaRef(SemaRef), HLSLNamespace(Namespace) { + : HLSLNamespace(Namespace), SemaRef(SemaRef) { ASTContext &AST = SemaRef.getASTContext(); IdentifierInfo &II = AST.Idents.get(Name, tok::TokenKind::identifier); @@ -91,6 +94,18 @@ struct BuiltinTypeDeclBuilder { HLSLNamespace->addDecl(Record); } + CXXRecordDecl *finalizeForwardDeclaration() { + // Force the QualType to be generated for the record declaration. In most + // cases this will happen naturally when something uses the type the + // QualType gets lazily created. Unfortunately, with our injected types if a + // type isn't used in a translation unit the QualType may not get + // automatically generated before a PCH is generated. To resolve this we + // just force that the QualType is generated after we create a forward + // declaration. + (void)Record->getASTContext().getRecordType(Record); + return Record; + } + BuiltinTypeDeclBuilder & addMemberVariable(StringRef Name, QualType Type, llvm::ArrayRef Attrs, AccessSpecifier Access = AccessSpecifier::AS_private) { @@ -176,6 +191,19 @@ struct BuiltinTypeDeclBuilder { return *this; } + BuiltinTypeDeclBuilder &addLoadMethods() { + if (Record->isCompleteDefinition()) + return *this; + + ASTContext &AST = Record->getASTContext(); + IdentifierInfo &II = AST.Idents.get("Load", tok::TokenKind::identifier); + DeclarationName Load(&II); + // TODO: We also need versions with status for CheckAccessFullyMapped. + addHandleAccessFunction(Load, /*IsConst=*/false, /*IsRef=*/false); + + return *this; + } + FieldDecl *getResourceHandleField() { auto I = Fields.find("__handle"); assert(I != Fields.end() && @@ -231,6 +259,8 @@ struct BuiltinTypeDeclBuilder { BuiltinTypeDeclBuilder &addDecrementCounterMethod(); BuiltinTypeDeclBuilder &addHandleAccessFunction(DeclarationName &Name, bool IsConst, bool IsRef); + BuiltinTypeDeclBuilder &addAppendMethod(); + BuiltinTypeDeclBuilder &addConsumeMethod(); }; struct TemplateParameterListBuilder { @@ -308,9 +338,9 @@ struct TemplateParameterListBuilder { Context, // AST context Builder.Record->getDeclContext(), // DeclContext SourceLocation(), SourceLocation(), - /*depth=*/0, // Depth in the template parameter list - /*position=*/0, // Position in the template parameter list - /*id=*/nullptr, // Identifier for 'T' + /*D=*/0, // Depth in the template parameter list + /*P=*/0, // Position in the template parameter list + /*Id=*/nullptr, // Identifier for 'T' /*Typename=*/true, // Indicates this is a 'typename' or 'class' /*ParameterPack=*/false, // Not a parameter pack /*HasTypeConstraint=*/false // Has no type constraint @@ -428,14 +458,26 @@ struct BuiltinTypeMethodBuilder { llvm::SmallVector StmtsList; // Argument placeholders, inspired by std::placeholder. These are the indices - // of arguments to forward to `callBuiltin`, and additionally `Handle` which - // refers to the resource handle. - enum class PlaceHolder { _0, _1, _2, _3, Handle = 127 }; + // of arguments to forward to `callBuiltin` and other method builder methods. + // Additional special values are: + // Handle - refers to the resource handle. + // LastStmt - refers to the last statement in the method body; referencing + // LastStmt will remove the statement from the method body since + // it will be linked from the new expression being constructed. + enum class PlaceHolder { _0, _1, _2, _3, Handle = 128, LastStmt }; Expr *convertPlaceholder(PlaceHolder PH) { if (PH == PlaceHolder::Handle) return getResourceHandleExpr(); + if (PH == PlaceHolder::LastStmt) { + assert(!StmtsList.empty() && "no statements in the list"); + Stmt *LastStmt = StmtsList.pop_back_val(); + assert(isa(LastStmt) && + "last statement does not have a value"); + return cast(LastStmt)->getExprStmt(); + } + ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); ParmVarDecl *ParamDecl = Method->getParamDecl(static_cast(PH)); return DeclRefExpr::Create( @@ -558,17 +600,25 @@ struct BuiltinTypeMethodBuilder { return *this; } - BuiltinTypeMethodBuilder &dereference() { - assert(!StmtsList.empty() && "Nothing to dereference"); - ASTContext &AST = DeclBuilder.SemaRef.getASTContext(); + template + BuiltinTypeMethodBuilder &assign(TLHS LHS, TRHS RHS) { + Expr *LHSExpr = convertPlaceholder(LHS); + Expr *RHSExpr = convertPlaceholder(RHS); + Stmt *AssignStmt = BinaryOperator::Create( + DeclBuilder.SemaRef.getASTContext(), LHSExpr, RHSExpr, BO_Assign, + LHSExpr->getType(), ExprValueKind::VK_PRValue, + ExprObjectKind::OK_Ordinary, SourceLocation(), FPOptionsOverride()); + StmtsList.push_back(AssignStmt); + return *this; + } - Expr *LastExpr = dyn_cast(StmtsList.back()); - assert(LastExpr && "No expression to dereference"); - Expr *Deref = UnaryOperator::Create( - AST, LastExpr, UO_Deref, LastExpr->getType()->getPointeeType(), - VK_PRValue, OK_Ordinary, SourceLocation(), - /*CanOverflow=*/false, FPOptionsOverride()); - StmtsList.pop_back(); + template BuiltinTypeMethodBuilder &dereference(T Ptr) { + Expr *PtrExpr = convertPlaceholder(Ptr); + Expr *Deref = + UnaryOperator::Create(DeclBuilder.SemaRef.getASTContext(), PtrExpr, + UO_Deref, PtrExpr->getType()->getPointeeType(), + VK_PRValue, OK_Ordinary, SourceLocation(), + /*CanOverflow=*/false, FPOptionsOverride()); StmtsList.push_back(Deref); return *this; } @@ -670,7 +720,35 @@ BuiltinTypeDeclBuilder::addHandleAccessFunction(DeclarationName &Name, .addParam("Index", AST.UnsignedIntTy) .callBuiltin("__builtin_hlsl_resource_getpointer", ElemPtrTy, PH::Handle, PH::_0) - .dereference() + .dereference(PH::LastStmt) + .finalizeMethod(); +} + +BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addAppendMethod() { + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + ASTContext &AST = SemaRef.getASTContext(); + QualType ElemTy = getHandleElementType(); + return BuiltinTypeMethodBuilder(*this, "Append", AST.VoidTy) + .addParam("value", ElemTy) + .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy, + PH::Handle, getConstantIntExpr(1)) + .callBuiltin("__builtin_hlsl_resource_getpointer", + AST.getPointerType(ElemTy), PH::Handle, PH::LastStmt) + .dereference(PH::LastStmt) + .assign(PH::LastStmt, PH::_0) + .finalizeMethod(); +} + +BuiltinTypeDeclBuilder &BuiltinTypeDeclBuilder::addConsumeMethod() { + using PH = BuiltinTypeMethodBuilder::PlaceHolder; + ASTContext &AST = SemaRef.getASTContext(); + QualType ElemTy = getHandleElementType(); + return BuiltinTypeMethodBuilder(*this, "Consume", ElemTy) + .callBuiltin("__builtin_hlsl_buffer_update_counter", AST.UnsignedIntTy, + PH::Handle, getConstantIntExpr(-1)) + .callBuiltin("__builtin_hlsl_resource_getpointer", + AST.getPointerType(ElemTy), PH::Handle, PH::LastStmt) + .dereference(PH::LastStmt) .finalizeMethod(); } @@ -786,7 +864,7 @@ static Expr *constructTypedBufferConstraintExpr(Sema &S, SourceLocation NameLoc, TemplateTypeParmDecl *T) { ASTContext &Context = S.getASTContext(); - // Obtain the QualType for 'unsigned long' + // Obtain the QualType for 'bool' QualType BoolTy = Context.BoolTy; // Create a QualType that points to this TemplateTypeParmDecl @@ -812,9 +890,9 @@ static ConceptDecl *constructTypedBufferConceptDecl(Sema &S, IdentifierInfo &ElementTypeII = Context.Idents.get("element_type"); TemplateTypeParmDecl *T = TemplateTypeParmDecl::Create( Context, NSD->getDeclContext(), DeclLoc, DeclLoc, - /*depth=*/0, - /*position=*/0, - /*id=*/&ElementTypeII, + /*D=*/0, + /*P=*/0, + /*Id=*/&ElementTypeII, /*Typename=*/true, /*ParameterPack=*/false); @@ -849,31 +927,33 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { constructTypedBufferConceptDecl(*SemaPtr, HLSLNamespace); Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWBuffer") .addSimpleTemplateParams({"element_type"}, TypedBufferConcept) - .Record; + .finalizeForwardDeclaration(); onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::TypedBuffer, /*IsROV=*/false, /*RawBuffer=*/false) .addArraySubscriptOperators() + .addLoadMethods() .completeDefinition(); }); Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RasterizerOrderedBuffer") .addSimpleTemplateParams({"element_type"}) - .Record; + .finalizeForwardDeclaration(); onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::TypedBuffer, /*IsROV=*/true, /*RawBuffer=*/false) .addArraySubscriptOperators() + .addLoadMethods() .completeDefinition(); }); Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "StructuredBuffer") .addSimpleTemplateParams({"element_type"}) - .Record; + .finalizeForwardDeclaration(); onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, ResourceKind::RawBuffer, /*IsROV=*/false, /*RawBuffer=*/true) @@ -883,7 +963,7 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWStructuredBuffer") .addSimpleTemplateParams({"element_type"}) - .Record; + .finalizeForwardDeclaration(); onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer, /*IsROV=*/false, /*RawBuffer=*/true) @@ -896,27 +976,29 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "AppendStructuredBuffer") .addSimpleTemplateParams({"element_type"}) - .Record; + .finalizeForwardDeclaration(); onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer, /*IsROV=*/false, /*RawBuffer=*/true) + .addAppendMethod() .completeDefinition(); }); Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "ConsumeStructuredBuffer") .addSimpleTemplateParams({"element_type"}) - .Record; + .finalizeForwardDeclaration(); onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer, /*IsROV=*/false, /*RawBuffer=*/true) + .addConsumeMethod() .completeDefinition(); }); Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RasterizerOrderedStructuredBuffer") .addSimpleTemplateParams({"element_type"}) - .Record; + .finalizeForwardDeclaration(); onCompletion(Decl, [this](CXXRecordDecl *Decl) { setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer, /*IsROV=*/true, /*RawBuffer=*/true) @@ -925,6 +1007,32 @@ void HLSLExternalSemaSource::defineHLSLTypesWithForwardDeclarations() { .addDecrementCounterMethod() .completeDefinition(); }); + + Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "ByteAddressBuffer") + .finalizeForwardDeclaration(); + onCompletion(Decl, [this](CXXRecordDecl *Decl) { + setupBufferType(Decl, *SemaPtr, ResourceClass::SRV, ResourceKind::RawBuffer, + /*IsROV=*/false, + /*RawBuffer=*/true) + .completeDefinition(); + }); + Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, "RWByteAddressBuffer") + .finalizeForwardDeclaration(); + onCompletion(Decl, [this](CXXRecordDecl *Decl) { + setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer, + /*IsROV=*/false, + /*RawBuffer=*/true) + .completeDefinition(); + }); + Decl = BuiltinTypeDeclBuilder(*SemaPtr, HLSLNamespace, + "RasterizerOrderedByteAddressBuffer") + .finalizeForwardDeclaration(); + onCompletion(Decl, [this](CXXRecordDecl *Decl) { + setupBufferType(Decl, *SemaPtr, ResourceClass::UAV, ResourceKind::RawBuffer, + /*IsROV=*/true, + /*RawBuffer=*/true) + .completeDefinition(); + }); } void HLSLExternalSemaSource::onCompletion(CXXRecordDecl *Record, diff --git a/clang/lib/Sema/MultiplexExternalSemaSource.cpp b/clang/lib/Sema/MultiplexExternalSemaSource.cpp index cd44483b5cbe0..54944267b4868 100644 --- a/clang/lib/Sema/MultiplexExternalSemaSource.cpp +++ b/clang/lib/Sema/MultiplexExternalSemaSource.cpp @@ -115,6 +115,23 @@ FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) { return AnyDeclsFound; } +bool MultiplexExternalSemaSource::LoadExternalSpecializations( + const Decl *D, bool OnlyPartial) { + bool Loaded = false; + for (size_t i = 0; i < Sources.size(); ++i) + Loaded |= Sources[i]->LoadExternalSpecializations(D, OnlyPartial); + return Loaded; +} + +bool MultiplexExternalSemaSource::LoadExternalSpecializations( + const Decl *D, ArrayRef TemplateArgs) { + bool AnyNewSpecsLoaded = false; + for (size_t i = 0; i < Sources.size(); ++i) + AnyNewSpecsLoaded |= + Sources[i]->LoadExternalSpecializations(D, TemplateArgs); + return AnyNewSpecsLoaded; +} + void MultiplexExternalSemaSource::completeVisibleDeclsMap(const DeclContext *DC){ for(size_t i = 0; i < Sources.size(); ++i) Sources[i]->completeVisibleDeclsMap(DC); diff --git a/clang/lib/Sema/SemaAPINotes.cpp b/clang/lib/Sema/SemaAPINotes.cpp index 0dedfc490c86f..4f79775bc5e91 100644 --- a/clang/lib/Sema/SemaAPINotes.cpp +++ b/clang/lib/Sema/SemaAPINotes.cpp @@ -511,6 +511,11 @@ static void ProcessAPINotes(Sema &S, FunctionOrMethod AnyFunc, AnyTypeChanged = true; } + // returns_(un)retained + if (!Info.SwiftReturnOwnership.empty()) + D->addAttr(SwiftAttrAttr::Create(S.Context, + "returns_" + Info.SwiftReturnOwnership)); + // Result type override. QualType OverriddenResultType; if (Metadata.IsActive && !Info.ResultType.empty() && diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp index 479f47962a7c3..44485e71d57a0 100644 --- a/clang/lib/Sema/SemaAttr.cpp +++ b/clang/lib/Sema/SemaAttr.cpp @@ -1310,6 +1310,8 @@ void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, } void Sema::AddImplicitMSFunctionNoBuiltinAttr(FunctionDecl *FD) { + if (FD->isDeleted() || FD->isDefaulted()) + return; SmallVector V(MSFunctionNoBuiltins.begin(), MSFunctionNoBuiltins.end()); if (!MSFunctionNoBuiltins.empty()) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index c4bb73b2924bc..55e891e3acf20 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -16,7 +16,6 @@ #include "clang/AST/ASTLambda.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/CharUnits.h" -#include "clang/AST/CommentDiagnostic.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclObjC.h" @@ -30,6 +29,7 @@ #include "clang/AST/StmtCXX.h" #include "clang/AST/Type.h" #include "clang/Basic/Builtins.h" +#include "clang/Basic/DiagnosticComment.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 4fd8ef6dbebf8..5d7ee09738377 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -7114,6 +7114,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_HLSLWaveSize: S.HLSL().handleWaveSizeAttr(D, AL); break; + case ParsedAttr::AT_HLSLSV_GroupThreadID: + S.HLSL().handleSV_GroupThreadIDAttr(D, AL); + break; case ParsedAttr::AT_HLSLSV_GroupID: S.HLSL().handleSV_GroupIDAttr(D, AL); break; diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 7e8e321c4b90e..c5a72cf812ebc 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -4074,24 +4074,28 @@ ExprResult Sema::ConvertMemberDefaultInitExpression(FieldDecl *FD, void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D, SourceLocation InitLoc, - Expr *InitExpr) { + ExprResult InitExpr) { // Pop the notional constructor scope we created earlier. PopFunctionScopeInfo(nullptr, D); - FieldDecl *FD = dyn_cast(D); - assert((isa(D) || FD->getInClassInitStyle() != ICIS_NoInit) && - "must set init style when field is created"); - - if (!InitExpr) { + // Microsoft C++'s property declaration cannot have a default member + // initializer. + if (isa(D)) { D->setInvalidDecl(); - if (FD) - FD->removeInClassInitializer(); return; } - if (DiagnoseUnexpandedParameterPack(InitExpr, UPPC_Initializer)) { + FieldDecl *FD = dyn_cast(D); + assert((FD && FD->getInClassInitStyle() != ICIS_NoInit) && + "must set init style when field is created"); + + if (!InitExpr.isUsable() || + DiagnoseUnexpandedParameterPack(InitExpr.get(), UPPC_Initializer)) { FD->setInvalidDecl(); - FD->removeInClassInitializer(); + ExprResult RecoveryInit = + CreateRecoveryExpr(InitLoc, InitLoc, {}, FD->getType()); + if (RecoveryInit.isUsable()) + FD->setInClassInitializer(RecoveryInit.get()); return; } @@ -7535,8 +7539,15 @@ void Sema::CheckExplicitlyDefaultedFunction(Scope *S, FunctionDecl *FD) { return; } - if (DefKind.isComparison()) - UnusedPrivateFields.clear(); + if (DefKind.isComparison()) { + auto PT = FD->getParamDecl(0)->getType(); + if (const CXXRecordDecl *RD = + PT.getNonReferenceType()->getAsCXXRecordDecl()) { + for (FieldDecl *Field : RD->fields()) { + UnusedPrivateFields.remove(Field); + } + } + } if (DefKind.isSpecialMember() ? CheckExplicitlyDefaultedSpecialMember(cast(FD), @@ -11920,7 +11931,7 @@ bool Sema::isStdInitializerList(QualType Ty, QualType *Element) { if (TemplateClass->getIdentifier() != &PP.getIdentifierTable().get("initializer_list") || !getStdNamespace()->InEnclosingNamespaceSetOf( - TemplateClass->getDeclContext())) + TemplateClass->getNonTransparentDeclContext())) return false; // This is a template called std::initializer_list, but is it the right // template? diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp index ecfd79a50542c..2be6af293ed54 100644 --- a/clang/lib/Sema/SemaExceptionSpec.cpp +++ b/clang/lib/Sema/SemaExceptionSpec.cpp @@ -1205,15 +1205,16 @@ CanThrowResult Sema::canThrow(const Stmt *S) { if (DTy.isNull() || DTy->isDependentType()) { CT = CT_Dependent; } else { - CT = canCalleeThrow(*this, DE, DE->getOperatorDelete()); - if (const RecordType *RT = DTy->getAs()) { - const CXXRecordDecl *RD = cast(RT->getDecl()); - const CXXDestructorDecl *DD = RD->getDestructor(); - if (DD) - CT = mergeCanThrow(CT, canCalleeThrow(*this, DE, DD)); + const FunctionDecl *OperatorDelete = DE->getOperatorDelete(); + CT = canCalleeThrow(*this, DE, OperatorDelete); + if (!OperatorDelete->isDestroyingOperatorDelete()) { + if (const auto *RD = DTy->getAsCXXRecordDecl()) { + if (const CXXDestructorDecl *DD = RD->getDestructor()) + CT = mergeCanThrow(CT, canCalleeThrow(*this, DE, DD)); + } + if (CT == CT_Can) + return CT; } - if (CT == CT_Can) - return CT; } return mergeCanThrow(CT, canSubStmtsThrow(*this, DE)); } @@ -1395,6 +1396,8 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Expr::ConceptSpecializationExprClass: case Expr::RequiresExprClass: case Expr::HLSLOutArgExprClass: + case Stmt::OpenACCEnterDataConstructClass: + case Stmt::OpenACCExitDataConstructClass: // These expressions can never throw. return CT_Cannot; @@ -1406,6 +1409,8 @@ CanThrowResult Sema::canThrow(const Stmt *S) { case Stmt::OpenACCComputeConstructClass: case Stmt::OpenACCLoopConstructClass: case Stmt::OpenACCCombinedConstructClass: + case Stmt::OpenACCDataConstructClass: + case Stmt::OpenACCHostDataConstructClass: case Stmt::AttributedStmtClass: case Stmt::BreakStmtClass: case Stmt::CapturedStmtClass: diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4ffce2c123661..20bf6f7f6f28f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5587,10 +5587,6 @@ static FieldDecl *FindFieldDeclInstantiationPattern(const ASTContext &Ctx, ExprResult Sema::BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field) { assert(Field->hasInClassInitializer()); - // If we might have already tried and failed to instantiate, don't try again. - if (Field->isInvalidDecl()) - return ExprError(); - CXXThisScopeRAII This(*this, Field->getParent(), Qualifiers()); auto *ParentRD = cast(Field->getParent()); @@ -5948,7 +5944,7 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, SmallVector AllArgs; VariadicCallType CallType = getVariadicCallType(FDecl, Proto, Fn); - Invalid = GatherArgumentsForCall(Call->getBeginLoc(), FDecl, Proto, 0, Args, + Invalid = GatherArgumentsForCall(Call->getExprLoc(), FDecl, Proto, 0, Args, AllArgs, CallType); if (Invalid) return true; @@ -11843,7 +11839,9 @@ static void diagnoseTautologicalComparison(Sema &S, SourceLocation Loc, RHSStripped->getType()->isArrayType()) { auto IsDeprArrayComparionIgnored = S.getDiagnostics().isIgnored(diag::warn_depr_array_comparison, Loc); - auto DiagID = !S.getLangOpts().CPlusPlus20 || IsDeprArrayComparionIgnored + auto DiagID = S.getLangOpts().CPlusPlus26 + ? diag::warn_array_comparison_cxx26 + : !S.getLangOpts().CPlusPlus20 || IsDeprArrayComparionIgnored ? diag::warn_array_comparison : diag::warn_depr_array_comparison; S.Diag(Loc, DiagID) << LHS->getSourceRange() << RHS->getSourceRange() @@ -19295,7 +19293,7 @@ static ExprResult rebuildPotentialResultsAsNonOdrUsed(Sema &S, Expr *E, if (VD->getType()->isReferenceType()) return true; if (auto *RD = VD->getType()->getAsCXXRecordDecl()) - if (RD->hasMutableFields()) + if (RD->hasDefinition() && RD->hasMutableFields()) return true; if (!VD->isUsableInConstantExpressions(S.Context)) return true; diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index db9ea7fb66e05..caea13b192ad5 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -3747,7 +3747,7 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, } else if (!Pointee->isDependentType()) { // FIXME: This can result in errors if the definition was imported from a // module but is hidden. - if (!Pointee->isStructureOrClassType() || + if (Pointee->isEnumeralType() || !RequireCompleteType(StartLoc, Pointee, LangOpts.CPlusPlus26 ? diag::err_delete_incomplete diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp index 88db3e1254119..600c800029fd0 100644 --- a/clang/lib/Sema/SemaHLSL.cpp +++ b/clang/lib/Sema/SemaHLSL.cpp @@ -434,6 +434,7 @@ void SemaHLSL::CheckSemanticAnnotation( switch (AnnotationAttr->getKind()) { case attr::HLSLSV_DispatchThreadID: case attr::HLSLSV_GroupIndex: + case attr::HLSLSV_GroupThreadID: case attr::HLSLSV_GroupID: if (ST == llvm::Triple::Compute) return; @@ -787,6 +788,15 @@ void SemaHLSL::handleSV_DispatchThreadIDAttr(Decl *D, const ParsedAttr &AL) { HLSLSV_DispatchThreadIDAttr(getASTContext(), AL)); } +void SemaHLSL::handleSV_GroupThreadIDAttr(Decl *D, const ParsedAttr &AL) { + auto *VD = cast(D); + if (!diagnoseInputIDType(VD->getType(), AL)) + return; + + D->addAttr(::new (getASTContext()) + HLSLSV_GroupThreadIDAttr(getASTContext(), AL)); +} + void SemaHLSL::handleSV_GroupIDAttr(Decl *D, const ParsedAttr &AL) { auto *VD = cast(D); if (!diagnoseInputIDType(VD->getType(), AL)) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 7c03a12e81280..5909457b04e66 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -745,6 +745,7 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field, if (Field->hasInClassInitializer()) { if (VerifyOnly) return; + ExprResult DIE; { // Enter a default initializer rebuild context, then we can support diff --git a/clang/lib/Sema/SemaOpenACC.cpp b/clang/lib/Sema/SemaOpenACC.cpp index 30491d6f3a3bd..11c18358a3aa0 100644 --- a/clang/lib/Sema/SemaOpenACC.cpp +++ b/clang/lib/Sema/SemaOpenACC.cpp @@ -37,6 +37,10 @@ bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K, case OpenACCDirectiveKind::Serial: case OpenACCDirectiveKind::Kernels: case OpenACCDirectiveKind::Loop: + case OpenACCDirectiveKind::Data: + case OpenACCDirectiveKind::EnterData: + case OpenACCDirectiveKind::ExitData: + case OpenACCDirectiveKind::HostData: if (!IsStmt) return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K; break; @@ -404,6 +408,49 @@ bool doesClauseApplyToDirective(OpenACCDirectiveKind DirectiveKind, return false; } } + case OpenACCClauseKind::Finalize: { + switch (DirectiveKind) { + case OpenACCDirectiveKind::ExitData: + return true; + default: + return false; + } + } + case OpenACCClauseKind::IfPresent: { + switch (DirectiveKind) { + case OpenACCDirectiveKind::HostData: + case OpenACCDirectiveKind::Update: + return true; + default: + return false; + } + } + case OpenACCClauseKind::Delete: { + switch (DirectiveKind) { + case OpenACCDirectiveKind::ExitData: + return true; + default: + return false; + } + } + + case OpenACCClauseKind::Detach: { + switch (DirectiveKind) { + case OpenACCDirectiveKind::ExitData: + return true; + default: + return false; + } + } + + case OpenACCClauseKind::UseDevice: { + switch (DirectiveKind) { + case OpenACCDirectiveKind::HostData: + return true; + default: + return false; + } + } } default: @@ -431,11 +478,12 @@ bool checkAlreadyHasClauseOfKind( bool checkValidAfterDeviceType( SemaOpenACC &S, const OpenACCDeviceTypeClause &DeviceTypeClause, const SemaOpenACC::OpenACCParsedClause &NewClause) { - // This is only a requirement on compute and loop constructs so far, so this - // is fine otherwise. + // This is only a requirement on compute, combined, data and loop constructs + // so far, so this is fine otherwise. if (!isOpenACCComputeDirectiveKind(NewClause.getDirectiveKind()) && !isOpenACCCombinedDirectiveKind(NewClause.getDirectiveKind()) && - NewClause.getDirectiveKind() != OpenACCDirectiveKind::Loop) + NewClause.getDirectiveKind() != OpenACCDirectiveKind::Loop && + NewClause.getDirectiveKind() != OpenACCDirectiveKind::Data) return false; // OpenACC3.3: Section 2.4: Clauses that precede any device_type clause are @@ -500,6 +548,16 @@ bool checkValidAfterDeviceType( default: break; } + } else if (NewClause.getDirectiveKind() == OpenACCDirectiveKind::Data) { + // OpenACC3.3 section 2.6.5: Only the async and wait clauses may follow a + // device_type clause. + switch (NewClause.getClauseKind()) { + case OpenACCClauseKind::Async: + case OpenACCClauseKind::Wait: + return false; + default: + break; + } } S.Diag(NewClause.getBeginLoc(), diag::err_acc_clause_after_device_type) << NewClause.getClauseKind() << DeviceTypeClause.getClauseKind() @@ -572,14 +630,6 @@ class SemaOpenACCClauseVisitor { OpenACCClause *SemaOpenACCClauseVisitor::VisitDefaultClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute'/'combined' constructs, - // and 'compute'/'combined' constructs are the only construct that can do - // anything with this yet, so skip/treat as unimplemented in this case. - // Only 'data' is left. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) - return isNotImplemented(); - // Don't add an invalid clause to the AST. if (Clause.getDefaultClauseKind() == OpenACCDefaultClauseKind::Invalid) return nullptr; @@ -626,16 +676,20 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitTileClause( OpenACCClause *SemaOpenACCClauseVisitor::VisitIfClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute'/'combined' constructs, - // and 'compute'/'combined' constructs are the only construct that can do - // anything with this yet, so skip/treat as unimplemented in this case. + // Restrictions only properly implemented on 'compute'/'combined'/'data' + // constructs, and 'compute'/'combined'/'data' constructs are the only + // constructs that can do anything with this yet, so skip/treat as + // unimplemented in this case. if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) + !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) && + !isOpenACCDataDirectiveKind(Clause.getDirectiveKind())) return isNotImplemented(); // There is no prose in the standard that says duplicates aren't allowed, // but this diagnostic is present in other compilers, as well as makes - // sense. + // sense. Prose DOES exist for 'data' and 'host_data', 'enter data' and 'exit + // data' both don't, but other implmementations do this. OpenACC issue 519 + // filed for the latter two. if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) return nullptr; @@ -719,11 +773,35 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause( << /*NoArgs=*/1 << Clause.getDirectiveKind() << MaxArgs << Clause.getIntExprs().size(); + // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop + // directive that has a gang clause and is within a compute construct that has + // a num_gangs clause with more than one explicit argument. + if (Clause.getIntExprs().size() > 1 && + isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { + auto *GangClauseItr = + llvm::find_if(ExistingClauses, llvm::IsaPred); + auto *ReductionClauseItr = + llvm::find_if(ExistingClauses, llvm::IsaPred); + + if (GangClauseItr != ExistingClauses.end() && + ReductionClauseItr != ExistingClauses.end()) { + SemaRef.Diag(Clause.getBeginLoc(), + diag::err_acc_gang_reduction_numgangs_conflict) + << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang + << Clause.getDirectiveKind() << /*is on combined directive=*/1; + SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(), + diag::note_acc_previous_clause_here); + SemaRef.Diag((*GangClauseItr)->getBeginLoc(), + diag::note_acc_previous_clause_here); + return nullptr; + } + } + // OpenACC 3.3 Section 2.5.4: // A reduction clause may not appear on a parallel construct with a // num_gangs clause that has more than one argument. - // TODO: OpenACC: Reduction on Combined Construct needs to do this too. - if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel && + if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel || + Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) && Clause.getIntExprs().size() > 1) { auto *Parallel = llvm::find_if(ExistingClauses, llvm::IsaPred); @@ -731,12 +809,33 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitNumGangsClause( if (Parallel != ExistingClauses.end()) { SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_reduction_num_gangs_conflict) - << Clause.getIntExprs().size(); + << /*>1 arg in first loc=*/1 << Clause.getClauseKind() + << Clause.getDirectiveKind() << OpenACCClauseKind::Reduction; SemaRef.Diag((*Parallel)->getBeginLoc(), diag::note_acc_previous_clause_here); return nullptr; } } + + // OpenACC 3.3 Section 2.9.2: + // An argument with no keyword or with the 'num' keyword is allowed only when + // the 'num_gangs' does not appear on the 'kernel' construct. + if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) { + auto GangClauses = llvm::make_filter_range( + ExistingClauses, llvm::IsaPred); + + for (auto *GC : GangClauses) { + if (cast(GC)->hasExprOfKind(OpenACCGangKind::Num)) { + SemaRef.Diag(Clause.getBeginLoc(), + diag::err_acc_num_arg_conflict_reverse) + << OpenACCClauseKind::NumGangs << OpenACCClauseKind::Gang + << /*Num argument*/ 1; + SemaRef.Diag(GC->getBeginLoc(), diag::note_acc_previous_clause_here); + return nullptr; + } + } + } + return OpenACCNumGangsClause::Create( Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getIntExprs(), Clause.getEndLoc()); @@ -750,6 +849,25 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitNumWorkersClause( if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) return nullptr; + // OpenACC 3.3 Section 2.9.2: + // An argument is allowed only when the 'num_workers' does not appear on the + // kernels construct. + if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) { + auto WorkerClauses = llvm::make_filter_range( + ExistingClauses, llvm::IsaPred); + + for (auto *WC : WorkerClauses) { + if (cast(WC)->hasIntExpr()) { + SemaRef.Diag(Clause.getBeginLoc(), + diag::err_acc_num_arg_conflict_reverse) + << OpenACCClauseKind::NumWorkers << OpenACCClauseKind::Worker + << /*num argument*/ 0; + SemaRef.Diag(WC->getBeginLoc(), diag::note_acc_previous_clause_here); + return nullptr; + } + } + } + assert(Clause.getIntExprs().size() == 1 && "Invalid number of expressions for NumWorkers"); return OpenACCNumWorkersClause::Create( @@ -765,6 +883,25 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause( if (checkAlreadyHasClauseOfKind(SemaRef, ExistingClauses, Clause)) return nullptr; + // OpenACC 3.3 Section 2.9.4: + // An argument is allowed only when the 'vector_length' does not appear on the + // 'kernels' construct. + if (Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop) { + auto VectorClauses = llvm::make_filter_range( + ExistingClauses, llvm::IsaPred); + + for (auto *VC : VectorClauses) { + if (cast(VC)->hasIntExpr()) { + SemaRef.Diag(Clause.getBeginLoc(), + diag::err_acc_num_arg_conflict_reverse) + << OpenACCClauseKind::VectorLength << OpenACCClauseKind::Vector + << /*num argument*/ 0; + SemaRef.Diag(VC->getBeginLoc(), diag::note_acc_previous_clause_here); + return nullptr; + } + } + } + assert(Clause.getIntExprs().size() == 1 && "Invalid number of expressions for NumWorkers"); return OpenACCVectorLengthClause::Create( @@ -774,11 +911,13 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorLengthClause( OpenACCClause *SemaOpenACCClauseVisitor::VisitAsyncClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute'/'combined' constructs, - // and 'compute'/'combined' constructs are the only construct that can do - // anything with this yet, so skip/treat as unimplemented in this case. + // Restrictions only properly implemented on 'compute'/'combined'/'data' + // constructs, and 'compute'/'combined'/'data' constructs are the only + // construct that can do anything with this yet, so skip/treat as + // unimplemented in this case. if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) + !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) && + !isOpenACCDataDirectiveKind(Clause.getDirectiveKind())) return isNotImplemented(); // There is no prose in the standard that says duplicates aren't allowed, @@ -819,12 +958,6 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitFirstPrivateClause( OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute'/'combined' constructs, - // and 'compute'/'combined' constructs are the only construct that can do - // anything with this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) - return isNotImplemented(); // ActOnVar ensured that everything is a valid variable reference, so there // really isn't anything to do here. GCC does some duplicate-finding, though // it isn't apparent in the standard where this is justified. @@ -836,11 +969,13 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitNoCreateClause( OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute'/'combined constructs, - // and 'compute'/'combined' constructs are the only construct that can do - // anything with this yet, so skip/treat as unimplemented in this case. + // Restrictions only properly implemented on 'compute'/'combined'/'data' + // constructs, and 'compute'/'combined'/'data' constructs are the only + // construct that can do anything with this yet, so skip/treat as + // unimplemented in this case. if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) + !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) && + !isOpenACCDataDirectiveKind(Clause.getDirectiveKind())) return isNotImplemented(); // ActOnVar ensured that everything is a valid variable reference, so there // really isn't anything to do here. GCC does some duplicate-finding, though @@ -853,11 +988,13 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitPresentClause( OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute'/'combined' constructs, - // and 'compute'/'combined' constructs are the only construct that can do - // anything with this yet, so skip/treat as unimplemented in this case. + // Restrictions only properly implemented on 'compute'/'combined'/'data' + // constructs, and 'compute'/'combined'/'data' constructs are the only + // construct that can do anything with this yet, so skip/treat as + // unimplemented in this case. if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) + !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) && + !isOpenACCDataDirectiveKind(Clause.getDirectiveKind())) return isNotImplemented(); // ActOnVar ensured that everything is a valid variable reference, so there // really isn't anything to do here. GCC does some duplicate-finding, though @@ -870,11 +1007,13 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyClause( OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute'/'combined' constructs, - // and 'compute'/'combined' constructs are the only construct that can do - // anything with this yet, so skip/treat as unimplemented in this case. + // Restrictions only properly implemented on 'compute'/'combined'/'data' + // constructs, and 'compute'/'combined'/'data' constructs are the only + // construct that can do anything with this yet, so skip/treat as + // unimplemented in this case. if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) + !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) && + !isOpenACCDataDirectiveKind(Clause.getDirectiveKind())) return isNotImplemented(); // ActOnVar ensured that everything is a valid variable reference, so there // really isn't anything to do here. GCC does some duplicate-finding, though @@ -887,11 +1026,13 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyInClause( OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute'/'combined' constructs, - // and 'compute'/'combined' constructs are the only construct that can do - // anything with this yet, so skip/treat as unimplemented in this case. + // Restrictions only properly implemented on 'compute'/'combined'/'data' + // constructs, and 'compute'/'combined'/'data' constructs are the only + // construct that can do anything with this yet, so skip/treat as + // unimplemented in this case. if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) + !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) && + !isOpenACCDataDirectiveKind(Clause.getDirectiveKind())) return isNotImplemented(); // ActOnVar ensured that everything is a valid variable reference, so there // really isn't anything to do here. GCC does some duplicate-finding, though @@ -904,12 +1045,6 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCopyOutClause( OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute'/'combined' constructs, - // and 'compute'/'combined' constructs are the only construct that can do - // anything with this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) - return isNotImplemented(); // ActOnVar ensured that everything is a valid variable reference, so there // really isn't anything to do here. GCC does some duplicate-finding, though // it isn't apparent in the standard where this is justified. @@ -921,13 +1056,6 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitCreateClause( OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute'/'combined' constructs, - // and 'compute'/'combined' constructs are the only construct that can do - // anything with this yet, so skip/treat as unimplemented in this case. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) - return isNotImplemented(); - // ActOnVar ensured that everything is a valid variable reference, but we // still have to make sure it is a pointer type. llvm::SmallVector VarList{Clause.getVarList()}; @@ -941,13 +1069,49 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitAttachClause( Clause.getEndLoc()); } +OpenACCClause *SemaOpenACCClauseVisitor::VisitDetachClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // ActOnVar ensured that everything is a valid variable reference, but we + // still have to make sure it is a pointer type. + llvm::SmallVector VarList{Clause.getVarList()}; + llvm::erase_if(VarList, [&](Expr *E) { + return SemaRef.CheckVarIsPointerType(OpenACCClauseKind::Detach, E); + }); + Clause.setVarListDetails(VarList, + /*IsReadOnly=*/false, /*IsZero=*/false); + return OpenACCDetachClause::Create(Ctx, Clause.getBeginLoc(), + Clause.getLParenLoc(), Clause.getVarList(), + Clause.getEndLoc()); +} + +OpenACCClause *SemaOpenACCClauseVisitor::VisitDeleteClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // ActOnVar ensured that everything is a valid variable reference, so there + // really isn't anything to do here. GCC does some duplicate-finding, though + // it isn't apparent in the standard where this is justified. + return OpenACCDeleteClause::Create(Ctx, Clause.getBeginLoc(), + Clause.getLParenLoc(), Clause.getVarList(), + Clause.getEndLoc()); +} + +OpenACCClause *SemaOpenACCClauseVisitor::VisitUseDeviceClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // ActOnVar ensured that everything is a valid variable or array, so nothing + // left to do here. + return OpenACCUseDeviceClause::Create( + Ctx, Clause.getBeginLoc(), Clause.getLParenLoc(), Clause.getVarList(), + Clause.getEndLoc()); +} + OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute'/'combined' constructs, - // and 'compute'/'combined' constructs are the only construct that can do - // anything with this yet, so skip/treat as unimplemented in this case. + // Restrictions only properly implemented on 'compute'/'combined'/'data' + // constructs, and 'compute'/'combined'/'data' constructs are the only + // construct that can do anything with this yet, so skip/treat as + // unimplemented in this case. if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) + !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) && + !isOpenACCDataDirectiveKind(Clause.getDirectiveKind())) return isNotImplemented(); // ActOnVar ensured that everything is a valid variable reference, but we @@ -966,11 +1130,13 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitDevicePtrClause( OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute'/'combined' constructs, - // and 'compute'/'combined' constructs are the only construct that can do - // anything with this yet, so skip/treat as unimplemented in this case. + // Restrictions only properly implemented on 'compute'/'combined'/'data' + // constructs, and 'compute'/'combined'/'data' constructs are the only + // construct that can do anything with this yet, so skip/treat as + // unimplemented in this case. if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) + !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) && + !isOpenACCDataDirectiveKind(Clause.getDirectiveKind())) return isNotImplemented(); return OpenACCWaitClause::Create( @@ -980,12 +1146,13 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWaitClause( OpenACCClause *SemaOpenACCClauseVisitor::VisitDeviceTypeClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute', 'combined', and - // 'loop' constructs, and 'compute'/'combined'/'loop' constructs are the only - // construct that can do anything with this yet, so skip/treat as + // Restrictions only properly implemented on 'compute', 'combined', 'data' and + // 'loop' constructs, and 'compute'/'combined'/'data'/'loop' constructs are + // the only construct that can do anything with this yet, so skip/treat as // unimplemented in this case. if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop && + Clause.getDirectiveKind() != OpenACCDirectiveKind::Data && !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) return isNotImplemented(); @@ -1033,62 +1200,237 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitIndependentClause( Clause.getEndLoc()); } +ExprResult CheckGangStaticExpr(SemaOpenACC &S, Expr *E) { + if (isa(E)) + return E; + return S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang, + E->getBeginLoc(), E); +} + +bool IsOrphanLoop(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) { + return DK == OpenACCDirectiveKind::Loop && + AssocKind == OpenACCDirectiveKind::Invalid; +} + +bool HasAssocKind(OpenACCDirectiveKind DK, OpenACCDirectiveKind AssocKind) { + return DK == OpenACCDirectiveKind::Loop && + AssocKind != OpenACCDirectiveKind::Invalid; +} + +ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, OpenACCGangKind GK, + OpenACCClauseKind CK, OpenACCDirectiveKind DK, + OpenACCDirectiveKind AssocKind) { + S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid) + << GK << CK << IsOrphanLoop(DK, AssocKind) << DK + << HasAssocKind(DK, AssocKind) << AssocKind; + return ExprError(); +} +ExprResult DiagIntArgInvalid(SemaOpenACC &S, Expr *E, StringRef TagKind, + OpenACCClauseKind CK, OpenACCDirectiveKind DK, + OpenACCDirectiveKind AssocKind) { + S.Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid) + << TagKind << CK << IsOrphanLoop(DK, AssocKind) << DK + << HasAssocKind(DK, AssocKind) << AssocKind; + return ExprError(); +} + +ExprResult CheckGangParallelExpr(SemaOpenACC &S, OpenACCDirectiveKind DK, + OpenACCDirectiveKind AssocKind, + OpenACCGangKind GK, Expr *E) { + switch (GK) { + case OpenACCGangKind::Static: + return CheckGangStaticExpr(S, E); + case OpenACCGangKind::Num: + // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel + // construct, or an orphaned loop construct, the gang clause behaves as + // follows. ... The num argument is not allowed. + return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind); + case OpenACCGangKind::Dim: { + // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel + // construct, or an orphaned loop construct, the gang clause behaves as + // follows. ... The dim argument must be a constant positive integer value + // 1, 2, or 3. + if (!E) + return ExprError(); + ExprResult Res = + S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang, + E->getBeginLoc(), E); + + if (!Res.isUsable()) + return Res; + + if (Res.get()->isInstantiationDependent()) + return Res; + + std::optional ICE = + Res.get()->getIntegerConstantExpr(S.getASTContext()); + + if (!ICE || *ICE <= 0 || ICE > 3) { + S.Diag(Res.get()->getBeginLoc(), diag::err_acc_gang_dim_value) + << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue(); + return ExprError(); + } + + return ExprResult{ + ConstantExpr::Create(S.getASTContext(), Res.get(), APValue{*ICE})}; + } + } + llvm_unreachable("Unknown gang kind in gang parallel check"); +} + +ExprResult CheckGangKernelsExpr(SemaOpenACC &S, + ArrayRef ExistingClauses, + OpenACCDirectiveKind DK, + OpenACCDirectiveKind AssocKind, + OpenACCGangKind GK, Expr *E) { + switch (GK) { + // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels + // construct, the gang clause behaves as follows. ... The dim argument is + // not allowed. + case OpenACCGangKind::Dim: + return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind); + case OpenACCGangKind::Num: { + // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels + // construct, the gang clause behaves as follows. ... An argument with no + // keyword or with num keyword is only allowed when num_gangs does not + // appear on the kernels construct. ... The region of a loop with the gang + // clause may not contain another loop with a gang clause unless within a + // nested compute region. + + // If this is a 'combined' construct, search the list of existing clauses. + // Else we need to search the containing 'kernel'. + auto Collection = isOpenACCCombinedDirectiveKind(DK) + ? ExistingClauses + : S.getActiveComputeConstructInfo().Clauses; + + const auto *Itr = + llvm::find_if(Collection, llvm::IsaPred); + + if (Itr != Collection.end()) { + S.Diag(E->getBeginLoc(), diag::err_acc_num_arg_conflict) + << "num" << OpenACCClauseKind::Gang << DK + << HasAssocKind(DK, AssocKind) << AssocKind + << OpenACCClauseKind::NumGangs; + + S.Diag((*Itr)->getBeginLoc(), diag::note_acc_previous_clause_here); + return ExprError(); + } + return ExprResult{E}; + } + case OpenACCGangKind::Static: + return CheckGangStaticExpr(S, E); + return ExprError(); + } + llvm_unreachable("Unknown gang kind in gang kernels check"); +} + +ExprResult CheckGangSerialExpr(SemaOpenACC &S, OpenACCDirectiveKind DK, + OpenACCDirectiveKind AssocKind, + OpenACCGangKind GK, Expr *E) { + switch (GK) { + // 'dim' and 'num' don't really make sense on serial, and GCC rejects them + // too, so we disallow them too. + case OpenACCGangKind::Dim: + case OpenACCGangKind::Num: + return DiagIntArgInvalid(S, E, GK, OpenACCClauseKind::Gang, DK, AssocKind); + case OpenACCGangKind::Static: + return CheckGangStaticExpr(S, E); + } + llvm_unreachable("Unknown gang kind in gang serial check"); +} + OpenACCClause *SemaOpenACCClauseVisitor::VisitVectorClause( SemaOpenACC::OpenACCParsedClause &Clause) { if (DiagIfSeqClause(Clause)) return nullptr; - // Restrictions only properly implemented on 'loop' constructs, and it is - // the only construct that can do anything with this, so skip/treat as - // unimplemented for the combined constructs. - if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) + + // Restrictions only properly implemented on 'loop'/'combined' constructs, and + // it is the only construct that can do anything with this, so skip/treat as + // unimplemented for the routine constructs. + if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop && + !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) return isNotImplemented(); Expr *IntExpr = Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr; if (IntExpr) { - switch (SemaRef.getActiveComputeConstructInfo().Kind) { - case OpenACCDirectiveKind::Invalid: - case OpenACCDirectiveKind::Parallel: - // No restriction on when 'parallel' can contain an argument. - break; - case OpenACCDirectiveKind::Serial: - // GCC disallows this, and there is no real good reason for us to permit - // it, so disallow until we come up with a use case that makes sense. - SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_int_arg_invalid) - << OpenACCClauseKind::Vector << "num" << /*serial=*/3; - IntExpr = nullptr; - break; - case OpenACCDirectiveKind::Kernels: { - const auto *Itr = - llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses, - llvm::IsaPred); - if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) { - SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) - << OpenACCClauseKind::Vector << /*vector_length=*/2; - SemaRef.Diag((*Itr)->getBeginLoc(), - diag::note_acc_previous_clause_here); - + if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { + switch (SemaRef.getActiveComputeConstructInfo().Kind) { + case OpenACCDirectiveKind::Invalid: + case OpenACCDirectiveKind::Parallel: + // No restriction on when 'parallel' can contain an argument. + break; + case OpenACCDirectiveKind::Serial: + // GCC disallows this, and there is no real good reason for us to permit + // it, so disallow until we come up with a use case that makes sense. + DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector, + Clause.getDirectiveKind(), + SemaRef.getActiveComputeConstructInfo().Kind); IntExpr = nullptr; + break; + case OpenACCDirectiveKind::Kernels: { + const auto *Itr = + llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses, + llvm::IsaPred); + if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) { + SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) + << "length" << OpenACCClauseKind::Vector + << Clause.getDirectiveKind() + << HasAssocKind(Clause.getDirectiveKind(), + SemaRef.getActiveComputeConstructInfo().Kind) + << SemaRef.getActiveComputeConstructInfo().Kind + << OpenACCClauseKind::VectorLength; + SemaRef.Diag((*Itr)->getBeginLoc(), + diag::note_acc_previous_clause_here); + + IntExpr = nullptr; + } + break; + } + default: + llvm_unreachable("Non compute construct in active compute construct"); + } + } else { + if (Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) { + DiagIntArgInvalid(SemaRef, IntExpr, "length", OpenACCClauseKind::Vector, + Clause.getDirectiveKind(), + SemaRef.getActiveComputeConstructInfo().Kind); + IntExpr = nullptr; + } else if (Clause.getDirectiveKind() == + OpenACCDirectiveKind::KernelsLoop) { + const auto *Itr = llvm::find_if( + ExistingClauses, llvm::IsaPred); + if (Itr != ExistingClauses.end()) { + SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) + << "length" << OpenACCClauseKind::Vector + << Clause.getDirectiveKind() + << HasAssocKind(Clause.getDirectiveKind(), + SemaRef.getActiveComputeConstructInfo().Kind) + << SemaRef.getActiveComputeConstructInfo().Kind + << OpenACCClauseKind::VectorLength; + SemaRef.Diag((*Itr)->getBeginLoc(), + diag::note_acc_previous_clause_here); + + IntExpr = nullptr; + } } - break; - } - default: - llvm_unreachable("Non compute construct in active compute construct"); } } - // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not - // contain a loop with a gang, worker, or vector clause unless within a nested - // compute region. - if (SemaRef.LoopVectorClauseLoc.isValid()) { - // This handles the 'inner loop' diagnostic, but we cannot set that we're on - // one of these until we get to the end of the construct. - SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) - << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector - << /*skip kernels construct info*/ 0; - SemaRef.Diag(SemaRef.LoopVectorClauseLoc, - diag::note_acc_previous_clause_here); - return nullptr; + if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { + // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not + // contain a loop with a gang, worker, or vector clause unless within a + // nested compute region. + if (SemaRef.LoopVectorClauseLoc.isValid()) { + // This handles the 'inner loop' diagnostic, but we cannot set that we're + // on one of these until we get to the end of the construct. + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) + << OpenACCClauseKind::Vector << OpenACCClauseKind::Vector + << /*skip kernels construct info*/ 0; + SemaRef.Diag(SemaRef.LoopVectorClauseLoc, + diag::note_acc_previous_clause_here); + return nullptr; + } } return OpenACCVectorClause::Create(Ctx, Clause.getBeginLoc(), @@ -1101,77 +1443,107 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitWorkerClause( if (DiagIfSeqClause(Clause)) return nullptr; - // Restrictions only properly implemented on 'loop' constructs, and it is - // the only construct that can do anything with this, so skip/treat as - // unimplemented for the combined constructs. - if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) + // Restrictions only properly implemented on 'loop'/'combined' constructs, and + // it is the only construct that can do anything with this, so skip/treat as + // unimplemented for the routine constructs. + if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop && + !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) return isNotImplemented(); Expr *IntExpr = Clause.getNumIntExprs() != 0 ? Clause.getIntExprs()[0] : nullptr; if (IntExpr) { - switch (SemaRef.getActiveComputeConstructInfo().Kind) { - case OpenACCDirectiveKind::Invalid: - SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_int_arg_invalid) - << OpenACCClauseKind::Worker << "num" << /*orphan=*/0; - IntExpr = nullptr; - break; - case OpenACCDirectiveKind::Parallel: - SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_int_arg_invalid) - << OpenACCClauseKind::Worker << "num" << /*parallel=*/1; - IntExpr = nullptr; - break; - case OpenACCDirectiveKind::Serial: - SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_int_arg_invalid) - << OpenACCClauseKind::Worker << "num" << /*serial=*/3; - IntExpr = nullptr; - break; - case OpenACCDirectiveKind::Kernels: { - const auto *Itr = - llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses, - llvm::IsaPred); - if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) { - SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) - << OpenACCClauseKind::Worker << /*num_workers=*/1; - SemaRef.Diag((*Itr)->getBeginLoc(), - diag::note_acc_previous_clause_here); - + if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { + switch (SemaRef.getActiveComputeConstructInfo().Kind) { + case OpenACCDirectiveKind::Invalid: + case OpenACCDirectiveKind::ParallelLoop: + case OpenACCDirectiveKind::SerialLoop: + case OpenACCDirectiveKind::Parallel: + case OpenACCDirectiveKind::Serial: + DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num, + OpenACCClauseKind::Worker, Clause.getDirectiveKind(), + SemaRef.getActiveComputeConstructInfo().Kind); IntExpr = nullptr; + break; + case OpenACCDirectiveKind::KernelsLoop: + case OpenACCDirectiveKind::Kernels: { + const auto *Itr = + llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses, + llvm::IsaPred); + if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) { + SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) + << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind() + << HasAssocKind(Clause.getDirectiveKind(), + SemaRef.getActiveComputeConstructInfo().Kind) + << SemaRef.getActiveComputeConstructInfo().Kind + << OpenACCClauseKind::NumWorkers; + SemaRef.Diag((*Itr)->getBeginLoc(), + diag::note_acc_previous_clause_here); + + IntExpr = nullptr; + } + break; + } + default: + llvm_unreachable("Non compute construct in active compute construct"); + } + } else { + if (Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop || + Clause.getDirectiveKind() == OpenACCDirectiveKind::SerialLoop) { + DiagIntArgInvalid(SemaRef, IntExpr, OpenACCGangKind::Num, + OpenACCClauseKind::Worker, Clause.getDirectiveKind(), + SemaRef.getActiveComputeConstructInfo().Kind); + IntExpr = nullptr; + } else { + assert(Clause.getDirectiveKind() == OpenACCDirectiveKind::KernelsLoop && + "Unknown combined directive kind?"); + const auto *Itr = llvm::find_if(ExistingClauses, + llvm::IsaPred); + if (Itr != ExistingClauses.end()) { + SemaRef.Diag(IntExpr->getBeginLoc(), diag::err_acc_num_arg_conflict) + << "num" << OpenACCClauseKind::Worker << Clause.getDirectiveKind() + << HasAssocKind(Clause.getDirectiveKind(), + SemaRef.getActiveComputeConstructInfo().Kind) + << SemaRef.getActiveComputeConstructInfo().Kind + << OpenACCClauseKind::NumWorkers; + SemaRef.Diag((*Itr)->getBeginLoc(), + diag::note_acc_previous_clause_here); + + IntExpr = nullptr; + } } - break; - } - default: - llvm_unreachable("Non compute construct in active compute construct"); } } - // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not - // contain a loop with a gang or worker clause unless within a nested compute - // region. - if (SemaRef.LoopWorkerClauseLoc.isValid()) { - // This handles the 'inner loop' diagnostic, but we cannot set that we're on - // one of these until we get to the end of the construct. - SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) - << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker - << /*skip kernels construct info*/ 0; - SemaRef.Diag(SemaRef.LoopWorkerClauseLoc, - diag::note_acc_previous_clause_here); - return nullptr; - } + if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { + // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not + // contain a loop with a gang or worker clause unless within a nested + // compute region. + if (SemaRef.LoopWorkerClauseLoc.isValid()) { + // This handles the 'inner loop' diagnostic, but we cannot set that we're + // on one of these until we get to the end of the construct. + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) + << OpenACCClauseKind::Worker << OpenACCClauseKind::Worker + << /*skip kernels construct info*/ 0; + SemaRef.Diag(SemaRef.LoopWorkerClauseLoc, + diag::note_acc_previous_clause_here); + return nullptr; + } - // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not - // contain a loop with a gang, worker, or vector clause unless within a nested - // compute region. - if (SemaRef.LoopVectorClauseLoc.isValid()) { - // This handles the 'inner loop' diagnostic, but we cannot set that we're on - // one of these until we get to the end of the construct. - SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) - << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector - << /*skip kernels construct info*/ 0; - SemaRef.Diag(SemaRef.LoopVectorClauseLoc, - diag::note_acc_previous_clause_here); - return nullptr; + // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not + // contain a loop with a gang, worker, or vector clause unless within a + // nested compute region. + if (SemaRef.LoopVectorClauseLoc.isValid()) { + // This handles the 'inner loop' diagnostic, but we cannot set that we're + // on one of these until we get to the end of the construct. + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) + << OpenACCClauseKind::Worker << OpenACCClauseKind::Vector + << /*skip kernels construct info*/ 0; + SemaRef.Diag(SemaRef.LoopVectorClauseLoc, + diag::note_acc_previous_clause_here); + return nullptr; + } } return OpenACCWorkerClause::Create(Ctx, Clause.getBeginLoc(), @@ -1187,36 +1559,43 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause( // Restrictions only properly implemented on 'loop' constructs, and it is // the only construct that can do anything with this, so skip/treat as // unimplemented for the combined constructs. - if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) + if (Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop && + !isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) return isNotImplemented(); // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop // directive that has a gang clause and is within a compute construct that has // a num_gangs clause with more than one explicit argument. - if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop && - SemaRef.getActiveComputeConstructInfo().Kind != - OpenACCDirectiveKind::Invalid) { + if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop && + SemaRef.getActiveComputeConstructInfo().Kind != + OpenACCDirectiveKind::Invalid) || + isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { // num_gangs clause on the active compute construct. - auto *NumGangsClauseItr = - llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses, - llvm::IsaPred); - - auto *ReductionClauseItr = - llvm::find_if(ExistingClauses, llvm::IsaPred); - - if (ReductionClauseItr != ExistingClauses.end() && - NumGangsClauseItr != - SemaRef.getActiveComputeConstructInfo().Clauses.end() && + auto ActiveComputeConstructContainer = + isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) + ? ExistingClauses + : SemaRef.getActiveComputeConstructInfo().Clauses; + auto *NumGangsClauseItr = llvm::find_if( + ActiveComputeConstructContainer, llvm::IsaPred); + + if (NumGangsClauseItr != ActiveComputeConstructContainer.end() && cast(*NumGangsClauseItr)->getIntExprs().size() > 1) { - SemaRef.Diag(Clause.getBeginLoc(), - diag::err_acc_gang_reduction_numgangs_conflict) - << OpenACCClauseKind::Gang << OpenACCClauseKind::Reduction; - SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(), - diag::note_acc_previous_clause_here); - SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(), - diag::note_acc_previous_clause_here); - return nullptr; + auto *ReductionClauseItr = + llvm::find_if(ExistingClauses, llvm::IsaPred); + + if (ReductionClauseItr != ExistingClauses.end()) { + SemaRef.Diag(Clause.getBeginLoc(), + diag::err_acc_gang_reduction_numgangs_conflict) + << OpenACCClauseKind::Gang << OpenACCClauseKind::Reduction + << Clause.getDirectiveKind() + << isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()); + SemaRef.Diag((*ReductionClauseItr)->getBeginLoc(), + diag::note_acc_previous_clause_here); + SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(), + diag::note_acc_previous_clause_here); + return nullptr; + } } } @@ -1229,31 +1608,13 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause( for (unsigned I = 0; I < Clause.getIntExprs().size(); ++I) { OpenACCGangKind GK = Clause.getGangKinds()[I]; - ExprResult ER = SemaRef.CheckGangExpr(GK, Clause.getIntExprs()[I]); + ExprResult ER = + SemaRef.CheckGangExpr(ExistingClauses, Clause.getDirectiveKind(), GK, + Clause.getIntExprs()[I]); if (!ER.isUsable()) continue; - // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels - // construct, the gang clause behaves as follows. ... An argument with no - // keyword or with num keyword is only allowed when num_gangs does not - // appear on the kernels construct. - if (SemaRef.getActiveComputeConstructInfo().Kind == - OpenACCDirectiveKind::Kernels && - GK == OpenACCGangKind::Num) { - const auto *Itr = - llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses, - llvm::IsaPred); - - if (Itr != SemaRef.getActiveComputeConstructInfo().Clauses.end()) { - SemaRef.Diag(ER.get()->getBeginLoc(), diag::err_acc_num_arg_conflict) - << OpenACCClauseKind::Gang << /*num_gangs=*/0; - SemaRef.Diag((*Itr)->getBeginLoc(), - diag::note_acc_previous_clause_here); - continue; - } - } - // OpenACC 3.3 2.9: 'gang-arg-list' may have at most one num, one dim, and // one static argument. if (ExistingElemLoc[static_cast(GK)].isValid()) { @@ -1269,52 +1630,73 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitGangClause( IntExprs.push_back(ER.get()); } - // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels - // construct, the gang clause behaves as follows. ... The region of a loop - // with a gang clause may not contain another loop with a gang clause unless - // within a nested compute region. - if (SemaRef.LoopGangClauseOnKernelLoc.isValid()) { - // This handles the 'inner loop' diagnostic, but we cannot set that we're on - // one of these until we get to the end of the construct. - SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) - << OpenACCClauseKind::Gang << OpenACCClauseKind::Gang - << /*kernels construct info*/ 1; - SemaRef.Diag(SemaRef.LoopGangClauseOnKernelLoc, - diag::note_acc_previous_clause_here); - return nullptr; - } + if (!isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { + // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels + // construct, the gang clause behaves as follows. ... The region of a loop + // with a gang clause may not contain another loop with a gang clause unless + // within a nested compute region. + if (SemaRef.LoopGangClauseOnKernel.Loc.isValid()) { + // This handles the 'inner loop' diagnostic, but we cannot set that we're + // on one of these until we get to the end of the construct. + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) + << OpenACCClauseKind::Gang << OpenACCClauseKind::Gang + << /*kernels construct info*/ 1 + << SemaRef.LoopGangClauseOnKernel.DirKind; + SemaRef.Diag(SemaRef.LoopGangClauseOnKernel.Loc, + diag::note_acc_previous_clause_here); + return nullptr; + } - // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not - // contain a loop with a gang or worker clause unless within a nested compute - // region. - if (SemaRef.LoopWorkerClauseLoc.isValid()) { - // This handles the 'inner loop' diagnostic, but we cannot set that we're on - // one of these until we get to the end of the construct. - SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) - << OpenACCClauseKind::Gang << OpenACCClauseKind::Worker - << /*kernels construct info*/ 1; - SemaRef.Diag(SemaRef.LoopWorkerClauseLoc, - diag::note_acc_previous_clause_here); - return nullptr; - } + // OpenACC 3.3 2.9.3: The region of a loop with a 'worker' clause may not + // contain a loop with a gang or worker clause unless within a nested + // compute region. + if (SemaRef.LoopWorkerClauseLoc.isValid()) { + // This handles the 'inner loop' diagnostic, but we cannot set that we're + // on one of these until we get to the end of the construct. + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) + << OpenACCClauseKind::Gang << OpenACCClauseKind::Worker + << /*!kernels construct info*/ 0; + SemaRef.Diag(SemaRef.LoopWorkerClauseLoc, + diag::note_acc_previous_clause_here); + return nullptr; + } - // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not - // contain a loop with a gang, worker, or vector clause unless within a nested - // compute region. - if (SemaRef.LoopVectorClauseLoc.isValid()) { - // This handles the 'inner loop' diagnostic, but we cannot set that we're on - // one of these until we get to the end of the construct. - SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) - << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector - << /*kernels construct info*/ 1; - SemaRef.Diag(SemaRef.LoopVectorClauseLoc, - diag::note_acc_previous_clause_here); - return nullptr; + // OpenACC 3.3 2.9.4: The region of a loop with a 'vector' clause may not + // contain a loop with a gang, worker, or vector clause unless within a + // nested compute region. + if (SemaRef.LoopVectorClauseLoc.isValid()) { + // This handles the 'inner loop' diagnostic, but we cannot set that we're + // on one of these until we get to the end of the construct. + SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_clause_in_clause_region) + << OpenACCClauseKind::Gang << OpenACCClauseKind::Vector + << /*!kernels construct info*/ 0; + SemaRef.Diag(SemaRef.LoopVectorClauseLoc, + diag::note_acc_previous_clause_here); + return nullptr; + } } - return SemaRef.CheckGangClause(ExistingClauses, Clause.getBeginLoc(), - Clause.getLParenLoc(), GangKinds, IntExprs, - Clause.getEndLoc()); + return SemaRef.CheckGangClause(Clause.getDirectiveKind(), ExistingClauses, + Clause.getBeginLoc(), Clause.getLParenLoc(), + GangKinds, IntExprs, Clause.getEndLoc()); +} + +OpenACCClause *SemaOpenACCClauseVisitor::VisitFinalizeClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + // There isn't anything to do here, this is only valid on one construct, and + // has no associated rules. + return OpenACCFinalizeClause::Create(Ctx, Clause.getBeginLoc(), + Clause.getEndLoc()); +} + +OpenACCClause *SemaOpenACCClauseVisitor::VisitIfPresentClause( + SemaOpenACC::OpenACCParsedClause &Clause) { + if (Clause.getDirectiveKind() != OpenACCDirectiveKind::HostData) + return isNotImplemented(); + // There isn't anything to do here, this is only valid on one construct, and + // has no associated rules. + return OpenACCIfPresentClause::Create(Ctx, Clause.getBeginLoc(), + Clause.getEndLoc()); } OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause( @@ -1358,41 +1740,39 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitSeqClause( OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause( SemaOpenACC::OpenACCParsedClause &Clause) { - // Restrictions only properly implemented on 'compute' constructs, and - // 'compute' constructs are the only construct that can do anything with - // this yet, so skip/treat as unimplemented in this case. - // TODO: OpenACC: Remove check once we get combined constructs for this clause. - if (!isOpenACCComputeDirectiveKind(Clause.getDirectiveKind()) && - Clause.getDirectiveKind() != OpenACCDirectiveKind::Loop) - return isNotImplemented(); - // OpenACC 3.3 Section 2.9.11: A reduction clause may not appear on a loop // directive that has a gang clause and is within a compute construct that has // a num_gangs clause with more than one explicit argument. - if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop && - SemaRef.getActiveComputeConstructInfo().Kind != - OpenACCDirectiveKind::Invalid) { + if ((Clause.getDirectiveKind() == OpenACCDirectiveKind::Loop && + SemaRef.getActiveComputeConstructInfo().Kind != + OpenACCDirectiveKind::Invalid) || + isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind())) { // num_gangs clause on the active compute construct. - auto *NumGangsClauseItr = - llvm::find_if(SemaRef.getActiveComputeConstructInfo().Clauses, - llvm::IsaPred); - - auto *GangClauseItr = - llvm::find_if(ExistingClauses, llvm::IsaPred); - - if (GangClauseItr != ExistingClauses.end() && - NumGangsClauseItr != - SemaRef.getActiveComputeConstructInfo().Clauses.end() && + auto ActiveComputeConstructContainer = + isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()) + ? ExistingClauses + : SemaRef.getActiveComputeConstructInfo().Clauses; + auto *NumGangsClauseItr = llvm::find_if( + ActiveComputeConstructContainer, llvm::IsaPred); + + if (NumGangsClauseItr != ActiveComputeConstructContainer.end() && cast(*NumGangsClauseItr)->getIntExprs().size() > 1) { - SemaRef.Diag(Clause.getBeginLoc(), - diag::err_acc_gang_reduction_numgangs_conflict) - << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang; - SemaRef.Diag((*GangClauseItr)->getBeginLoc(), - diag::note_acc_previous_clause_here); - SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(), - diag::note_acc_previous_clause_here); - return nullptr; + auto *GangClauseItr = + llvm::find_if(ExistingClauses, llvm::IsaPred); + + if (GangClauseItr != ExistingClauses.end()) { + SemaRef.Diag(Clause.getBeginLoc(), + diag::err_acc_gang_reduction_numgangs_conflict) + << OpenACCClauseKind::Reduction << OpenACCClauseKind::Gang + << Clause.getDirectiveKind() + << isOpenACCCombinedDirectiveKind(Clause.getDirectiveKind()); + SemaRef.Diag((*GangClauseItr)->getBeginLoc(), + diag::note_acc_previous_clause_here); + SemaRef.Diag((*NumGangsClauseItr)->getBeginLoc(), + diag::note_acc_previous_clause_here); + return nullptr; + } } } @@ -1416,7 +1796,8 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause( // OpenACC 3.3 Section 2.5.4: // A reduction clause may not appear on a parallel construct with a // num_gangs clause that has more than one argument. - if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel) { + if (Clause.getDirectiveKind() == OpenACCDirectiveKind::Parallel || + Clause.getDirectiveKind() == OpenACCDirectiveKind::ParallelLoop) { auto NumGangsClauses = llvm::make_filter_range( ExistingClauses, llvm::IsaPred); @@ -1427,7 +1808,8 @@ OpenACCClause *SemaOpenACCClauseVisitor::VisitReductionClause( if (NumExprs > 1) { SemaRef.Diag(Clause.getBeginLoc(), diag::err_acc_reduction_num_gangs_conflict) - << NumExprs; + << /*>1 arg in first loc=*/0 << Clause.getClauseKind() + << Clause.getDirectiveKind() << OpenACCClauseKind::NumGangs; SemaRef.Diag(NGC->getBeginLoc(), diag::note_acc_previous_clause_here); return nullptr; } @@ -1480,6 +1862,31 @@ void CollectActiveReductionClauses( } } +// Depth needs to be preserved for all associated statements that aren't +// supposed to modify the compute/combined/loop construct information. +bool PreserveLoopRAIIDepthInAssociatedStmtRAII(OpenACCDirectiveKind DK) { + switch (DK) { + case OpenACCDirectiveKind::Parallel: + case OpenACCDirectiveKind::ParallelLoop: + case OpenACCDirectiveKind::Serial: + case OpenACCDirectiveKind::SerialLoop: + case OpenACCDirectiveKind::Kernels: + case OpenACCDirectiveKind::KernelsLoop: + case OpenACCDirectiveKind::Loop: + return false; + case OpenACCDirectiveKind::Data: + case OpenACCDirectiveKind::HostData: + return true; + case OpenACCDirectiveKind::EnterData: + case OpenACCDirectiveKind::ExitData: + llvm_unreachable("Doesn't have an associated stmt"); + default: + case OpenACCDirectiveKind::Invalid: + llvm_unreachable("Unhandled directive kind?"); + } + llvm_unreachable("Unhandled directive kind?"); +} + } // namespace SemaOpenACC::SemaOpenACC(Sema &S) : SemaBase(S) {} @@ -1489,12 +1896,12 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII( ArrayRef UnInstClauses, ArrayRef Clauses) : SemaRef(S), OldActiveComputeConstructInfo(S.ActiveComputeConstructInfo), - DirKind(DK), OldLoopGangClauseOnKernelLoc(S.LoopGangClauseOnKernelLoc), + DirKind(DK), OldLoopGangClauseOnKernel(S.LoopGangClauseOnKernel), OldLoopWorkerClauseLoc(S.LoopWorkerClauseLoc), OldLoopVectorClauseLoc(S.LoopVectorClauseLoc), OldLoopWithoutSeqInfo(S.LoopWithoutSeqInfo), ActiveReductionClauses(S.ActiveReductionClauses), - LoopRAII(SemaRef, /*PreserveDepth=*/false) { + LoopRAII(SemaRef, PreserveLoopRAIIDepthInAssociatedStmtRAII(DirKind)) { // Compute constructs end up taking their 'loop'. if (DirKind == OpenACCDirectiveKind::Parallel || @@ -1510,7 +1917,7 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII( // within a nested compute region. // // Implement the 'unless within a nested compute region' part. - SemaRef.LoopGangClauseOnKernelLoc = {}; + SemaRef.LoopGangClauseOnKernel = {}; SemaRef.LoopWorkerClauseLoc = {}; SemaRef.LoopVectorClauseLoc = {}; SemaRef.LoopWithoutSeqInfo = {}; @@ -1524,8 +1931,7 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII( SetCollapseInfoBeforeAssociatedStmt(UnInstClauses, Clauses); SetTileInfoBeforeAssociatedStmt(UnInstClauses, Clauses); - // TODO: OpenACC: We need to set these 3, CollapseInfo, and TileInfo - SemaRef.LoopGangClauseOnKernelLoc = {}; + SemaRef.LoopGangClauseOnKernel = {}; SemaRef.LoopWorkerClauseLoc = {}; SemaRef.LoopVectorClauseLoc = {}; @@ -1548,7 +1954,7 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII( // This handles the 'outer loop' part of this. auto *Itr = llvm::find_if(Clauses, llvm::IsaPred); if (Itr != Clauses.end()) - SemaRef.LoopGangClauseOnKernelLoc = (*Itr)->getBeginLoc(); + SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(), DirKind}; } if (UnInstClauses.empty()) { @@ -1586,7 +1992,8 @@ SemaOpenACC::AssociatedStmtRAII::AssociatedStmtRAII( // This handles the 'outer loop' part of this. auto *Itr = llvm::find_if(Clauses, llvm::IsaPred); if (Itr != Clauses.end()) - SemaRef.LoopGangClauseOnKernelLoc = (*Itr)->getBeginLoc(); + SemaRef.LoopGangClauseOnKernel = {(*Itr)->getBeginLoc(), + OpenACCDirectiveKind::Kernels}; } if (UnInstClauses.empty()) { @@ -1670,24 +2077,23 @@ void SemaOpenACC::AssociatedStmtRAII::SetTileInfoBeforeAssociatedStmt( } SemaOpenACC::AssociatedStmtRAII::~AssociatedStmtRAII() { - SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo; - SemaRef.LoopGangClauseOnKernelLoc = OldLoopGangClauseOnKernelLoc; - SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc; - SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc; - SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo; - SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses); - if (DirKind == OpenACCDirectiveKind::Parallel || DirKind == OpenACCDirectiveKind::Serial || DirKind == OpenACCDirectiveKind::Kernels || + DirKind == OpenACCDirectiveKind::Loop || DirKind == OpenACCDirectiveKind::ParallelLoop || DirKind == OpenACCDirectiveKind::SerialLoop || DirKind == OpenACCDirectiveKind::KernelsLoop) { - // Nothing really to do here, the restorations above should be enough for - // now. - } else if (DirKind == OpenACCDirectiveKind::Loop) { - // Nothing really to do here, the LoopInConstruct should handle restorations - // correctly. + SemaRef.ActiveComputeConstructInfo = OldActiveComputeConstructInfo; + SemaRef.LoopGangClauseOnKernel = OldLoopGangClauseOnKernel; + SemaRef.LoopWorkerClauseLoc = OldLoopWorkerClauseLoc; + SemaRef.LoopVectorClauseLoc = OldLoopVectorClauseLoc; + SemaRef.LoopWithoutSeqInfo = OldLoopWithoutSeqInfo; + SemaRef.ActiveReductionClauses.swap(ActiveReductionClauses); + } else if (DirKind == OpenACCDirectiveKind::Data || + DirKind == OpenACCDirectiveKind::HostData) { + // Intentionally doesn't reset the Loop, Compute Construct, or reduction + // effects. } } @@ -1895,6 +2301,10 @@ void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K, case OpenACCDirectiveKind::SerialLoop: case OpenACCDirectiveKind::KernelsLoop: case OpenACCDirectiveKind::Loop: + case OpenACCDirectiveKind::Data: + case OpenACCDirectiveKind::EnterData: + case OpenACCDirectiveKind::ExitData: + case OpenACCDirectiveKind::HostData: // Nothing to do here, there is no real legalization that needs to happen // here as these constructs do not take any arguments. break; @@ -2038,6 +2448,15 @@ bool SemaOpenACC::CheckVarIsPointerType(OpenACCClauseKind ClauseKind, ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) { Expr *CurVarExpr = VarExpr->IgnoreParenImpCasts(); + // 'use_device' doesn't allow array subscript or array sections. + // OpenACC3.3 2.8: + // A 'var' in a 'use_device' clause must be the name of a variable or array. + if (CK == OpenACCClauseKind::UseDevice && + isa(CurVarExpr)) { + Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device); + return ExprError(); + } + // Sub-arrays/subscript-exprs are fine as long as the base is a // VarExpr/MemberExpr. So strip all of those off. while (isa(CurVarExpr)) { @@ -2058,16 +2477,20 @@ ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) { // If CK is a Reduction, this special cases for OpenACC3.3 2.5.15: "A var in a // reduction clause must be a scalar variable name, an aggregate variable // name, an array element, or a subarray. - // A MemberExpr that references a Field is valid. - if (CK != OpenACCClauseKind::Reduction) { + // If CK is a 'use_device', this also isn't valid, as it isn' the name of a + // variable or array. + // A MemberExpr that references a Field is valid for other clauses. + if (CK != OpenACCClauseKind::Reduction && + CK != OpenACCClauseKind::UseDevice) { if (const auto *ME = dyn_cast(CurVarExpr)) { if (isa(ME->getMemberDecl()->getCanonicalDecl())) return VarExpr; } } - // Referring to 'this' is always OK. - if (isa(CurVarExpr)) + // Referring to 'this' is ok for the most part, but for 'use_device' doesn't + // fall into 'variable or array name' + if (CK != OpenACCClauseKind::UseDevice && isa(CurVarExpr)) return VarExpr; // Nothing really we can do here, as these are dependent. So just return they @@ -2082,8 +2505,11 @@ ExprResult SemaOpenACC::ActOnVar(OpenACCClauseKind CK, Expr *VarExpr) { if (isa(CurVarExpr)) return ExprError(); - Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref) - << (CK != OpenACCClauseKind::Reduction); + if (CK == OpenACCClauseKind::UseDevice) + Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref_use_device); + else + Diag(VarExpr->getExprLoc(), diag::err_acc_not_a_var_ref) + << (CK != OpenACCClauseKind::Reduction); return ExprError(); } @@ -2328,111 +2754,53 @@ ExprResult SemaOpenACC::CheckCollapseLoopCount(Expr *LoopCount) { ConstantExpr::Create(getASTContext(), LoopCount, APValue{*ICE})}; } -namespace { -ExprResult CheckGangStaticExpr(SemaOpenACC &S, Expr *E) { - if (isa(E)) - return E; - return S.ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang, - E->getBeginLoc(), E); -} -} // namespace - -ExprResult SemaOpenACC::CheckGangExpr(OpenACCGangKind GK, Expr *E) { - // Gang Expr legality depends on the associated compute construct. - switch (ActiveComputeConstructInfo.Kind) { - case OpenACCDirectiveKind::Invalid: - case OpenACCDirectiveKind::Parallel: { - switch (GK) { - // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel - // construct, or an orphaned loop construct, the gang clause behaves as - // follows. ... The dim argument must be a constant positive integer value - // 1, 2, or 3. - case OpenACCGangKind::Dim: { - if (!E) - return ExprError(); - ExprResult Res = - ActOnIntExpr(OpenACCDirectiveKind::Invalid, OpenACCClauseKind::Gang, - E->getBeginLoc(), E); - - if (!Res.isUsable()) - return Res; - - if (Res.get()->isInstantiationDependent()) - return Res; - - std::optional ICE = - Res.get()->getIntegerConstantExpr(getASTContext()); - - if (!ICE || *ICE <= 0 || ICE > 3) { - Diag(Res.get()->getBeginLoc(), diag::err_acc_gang_dim_value) - << ICE.has_value() << ICE.value_or(llvm::APSInt{}).getExtValue(); - return ExprError(); - } - - return ExprResult{ - ConstantExpr::Create(getASTContext(), Res.get(), APValue{*ICE})}; - } - // OpenACC 3.3 2.9.2: When the parent compute construct is a parallel - // construct, or an orphaned loop construct, the gang clause behaves as - // follows. ... The num argument is not allowed. - case OpenACCGangKind::Num: - Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid) - << OpenACCClauseKind::Gang << GK - << (/*orphan/parallel=*/ActiveComputeConstructInfo.Kind == - OpenACCDirectiveKind::Parallel - ? 1 - : 0); - return ExprError(); - case OpenACCGangKind::Static: - return CheckGangStaticExpr(*this, E); - } - } break; - case OpenACCDirectiveKind::Kernels: { - switch (GK) { - // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels - // construct, the gang clause behaves as follows. ... The dim argument is - // not allowed. - case OpenACCGangKind::Dim: - Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid) - << OpenACCClauseKind::Gang << GK << /*kernels=*/2; - return ExprError(); - // OpenACC 3.3 2.9.2: When the parent compute construct is a kernels - // construct, the gang clause behaves as follows. ... An argument with no - // keyword or with num keyword is only allowed when num_gangs does not - // appear on the kernels construct. ... The region of a loop with the gang - // clause may not contain another loop with a gang clause unless within a - // nested compute region. - case OpenACCGangKind::Num: - // This isn't allowed if there is a 'num_gangs' on the kernel construct, - // and makes loop-with-gang-clause ill-formed inside of this 'loop', but - // nothing can be enforced here. - return ExprResult{E}; - case OpenACCGangKind::Static: - return CheckGangStaticExpr(*this, E); - } - } break; - case OpenACCDirectiveKind::Serial: { - switch (GK) { - // 'dim' and 'num' don't really make sense on serial, and GCC rejects them - // too, so we disallow them too. - case OpenACCGangKind::Dim: - case OpenACCGangKind::Num: - Diag(E->getBeginLoc(), diag::err_acc_int_arg_invalid) - << OpenACCClauseKind::Gang << GK << /*Kernels=*/3; - return ExprError(); - case OpenACCGangKind::Static: - return CheckGangStaticExpr(*this, E); +ExprResult +SemaOpenACC::CheckGangExpr(ArrayRef ExistingClauses, + OpenACCDirectiveKind DK, OpenACCGangKind GK, + Expr *E) { + // There are two cases for the enforcement here: the 'current' directive is a + // 'loop', where we need to check the active compute construct kind, or the + // current directive is a 'combined' construct, where we have to check the + // current one. + switch (DK) { + case OpenACCDirectiveKind::ParallelLoop: + return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK, + E); + case OpenACCDirectiveKind::SerialLoop: + return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK, + E); + case OpenACCDirectiveKind::KernelsLoop: + return CheckGangKernelsExpr(*this, ExistingClauses, DK, + ActiveComputeConstructInfo.Kind, GK, E); + case OpenACCDirectiveKind::Loop: + switch (ActiveComputeConstructInfo.Kind) { + case OpenACCDirectiveKind::Invalid: + case OpenACCDirectiveKind::Parallel: + case OpenACCDirectiveKind::ParallelLoop: + return CheckGangParallelExpr(*this, DK, ActiveComputeConstructInfo.Kind, + GK, E); + case OpenACCDirectiveKind::SerialLoop: + case OpenACCDirectiveKind::Serial: + return CheckGangSerialExpr(*this, DK, ActiveComputeConstructInfo.Kind, GK, + E); + case OpenACCDirectiveKind::KernelsLoop: + case OpenACCDirectiveKind::Kernels: + return CheckGangKernelsExpr(*this, ExistingClauses, DK, + ActiveComputeConstructInfo.Kind, GK, E); + default: + llvm_unreachable("Non compute construct in active compute construct?"); } - } break; default: - llvm_unreachable("Non compute construct in active compute construct?"); + // TODO: OpenACC: when we implement this on 'routine', we'll have to + // implement its checking here. + llvm_unreachable("Invalid directive kind for a Gang clause"); } - llvm_unreachable("Compute construct directive not handled?"); } OpenACCClause * -SemaOpenACC::CheckGangClause(ArrayRef ExistingClauses, +SemaOpenACC::CheckGangClause(OpenACCDirectiveKind DirKind, + ArrayRef ExistingClauses, SourceLocation BeginLoc, SourceLocation LParenLoc, ArrayRef GangKinds, ArrayRef IntExprs, SourceLocation EndLoc) { @@ -2457,7 +2825,7 @@ SemaOpenACC::CheckGangClause(ArrayRef ExistingClauses, if (const auto *DimVal = dyn_cast(DimExpr); DimVal && DimVal->getResultAsAPSInt() > 1) { Diag(DimVal->getBeginLoc(), diag::err_acc_gang_reduction_conflict) - << /*gang/reduction=*/0; + << /*gang/reduction=*/0 << DirKind; Diag((*ReductionItr)->getBeginLoc(), diag::note_acc_previous_clause_here); return nullptr; @@ -2474,30 +2842,29 @@ OpenACCClause *SemaOpenACC::CheckReductionClause( OpenACCDirectiveKind DirectiveKind, SourceLocation BeginLoc, SourceLocation LParenLoc, OpenACCReductionOperator ReductionOp, ArrayRef Vars, SourceLocation EndLoc) { - if (DirectiveKind == OpenACCDirectiveKind::Loop) { + if (DirectiveKind == OpenACCDirectiveKind::Loop || + isOpenACCCombinedDirectiveKind(DirectiveKind)) { // OpenACC 3.3 2.9.11: A reduction clause may not appear on a loop directive // that has a gang clause with a dim: argument whose value is greater // than 1. - const auto *GangItr = - llvm::find_if(ExistingClauses, llvm::IsaPred); + const auto GangClauses = llvm::make_filter_range( + ExistingClauses, llvm::IsaPred); - while (GangItr != ExistingClauses.end()) { - auto *GangClause = cast(*GangItr); + for (auto *GC : GangClauses) { + const auto *GangClause = cast(GC); for (unsigned I = 0; I < GangClause->getNumExprs(); ++I) { std::pair EPair = GangClause->getExpr(I); - // We know there is only 1 on this gang, so move onto the next gang. if (EPair.first != OpenACCGangKind::Dim) - break; + continue; if (const auto *DimVal = dyn_cast(EPair.second); DimVal && DimVal->getResultAsAPSInt() > 1) { Diag(BeginLoc, diag::err_acc_gang_reduction_conflict) - << /*reduction/gang=*/1; - Diag((*GangItr)->getBeginLoc(), diag::note_acc_previous_clause_here); + << /*reduction/gang=*/1 << DirectiveKind; + Diag(GangClause->getBeginLoc(), diag::note_acc_previous_clause_here); return nullptr; } } - ++GangItr; } } @@ -3159,8 +3526,35 @@ void SemaOpenACC::ActOnForStmtEnd(SourceLocation ForLoc, StmtResult Body) { } } -bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K, - SourceLocation StartLoc) { +namespace { +// Get a list of clause Kinds for diagnosing a list, joined by a commas and an +// 'or'. +std::string GetListOfClauses(llvm::ArrayRef Clauses) { + assert(!Clauses.empty() && "empty clause list not supported"); + + std::string Output; + llvm::raw_string_ostream OS{Output}; + + if (Clauses.size() == 1) { + OS << '\'' << Clauses[0] << '\''; + return Output; + } + + llvm::ArrayRef AllButLast{Clauses.begin(), + Clauses.end() - 1}; + + llvm::interleave( + AllButLast, [&](OpenACCClauseKind K) { OS << '\'' << K << '\''; }, + [&] { OS << ", "; }); + + OS << " or \'" << Clauses.back() << '\''; + return Output; +} +} // namespace + +bool SemaOpenACC::ActOnStartStmtDirective( + OpenACCDirectiveKind K, SourceLocation StartLoc, + ArrayRef Clauses) { SemaRef.DiscardCleanupsInEvaluationContext(); SemaRef.PopExpressionEvaluationContext(); @@ -3187,6 +3581,59 @@ bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K, << OpenACCClauseKind::Tile; } + // OpenACC3.3 2.6.5: At least one copy, copyin, copyout, create, no_create, + // present, deviceptr, attach, or default clause must appear on a 'data' + // construct. + if (K == OpenACCDirectiveKind::Data && + llvm::find_if(Clauses, + llvm::IsaPred) == Clauses.end()) + return Diag(StartLoc, diag::err_acc_construct_one_clause_of) + << K + << GetListOfClauses( + {OpenACCClauseKind::Copy, OpenACCClauseKind::CopyIn, + OpenACCClauseKind::CopyOut, OpenACCClauseKind::Create, + OpenACCClauseKind::NoCreate, OpenACCClauseKind::Present, + OpenACCClauseKind::DevicePtr, OpenACCClauseKind::Attach, + OpenACCClauseKind::Default}); + + // OpenACC3.3 2.6.6: At least one copyin, create, or attach clause must appear + // on an enter data directive. + if (K == OpenACCDirectiveKind::EnterData && + llvm::find_if(Clauses, + llvm::IsaPred) == Clauses.end()) + return Diag(StartLoc, diag::err_acc_construct_one_clause_of) + << K + << GetListOfClauses({ + OpenACCClauseKind::CopyIn, + OpenACCClauseKind::Create, + OpenACCClauseKind::Attach, + }); + // OpenACC3.3 2.6.6: At least one copyout, delete, or detach clause must + // appear on an exit data directive. + if (K == OpenACCDirectiveKind::ExitData && + llvm::find_if(Clauses, + llvm::IsaPred) == Clauses.end()) + return Diag(StartLoc, diag::err_acc_construct_one_clause_of) + << K + << GetListOfClauses({ + OpenACCClauseKind::CopyOut, + OpenACCClauseKind::Delete, + OpenACCClauseKind::Detach, + }); + + // OpenACC3.3 2.8: At least 'one use_device' clause must appear. + if (K == OpenACCDirectiveKind::HostData && + llvm::find_if(Clauses, llvm::IsaPred) == + Clauses.end()) + return Diag(StartLoc, diag::err_acc_construct_one_clause_of) + << K << GetListOfClauses({OpenACCClauseKind::UseDevice}); + return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true); } @@ -3220,6 +3667,24 @@ StmtResult SemaOpenACC::ActOnEndStmtDirective(OpenACCDirectiveKind K, getASTContext(), ActiveComputeConstructInfo.Kind, StartLoc, DirLoc, EndLoc, Clauses, AssocStmt.isUsable() ? AssocStmt.get() : nullptr); } + case OpenACCDirectiveKind::Data: { + return OpenACCDataConstruct::Create( + getASTContext(), StartLoc, DirLoc, EndLoc, Clauses, + AssocStmt.isUsable() ? AssocStmt.get() : nullptr); + } + case OpenACCDirectiveKind::EnterData: { + return OpenACCEnterDataConstruct::Create(getASTContext(), StartLoc, DirLoc, + EndLoc, Clauses); + } + case OpenACCDirectiveKind::ExitData: { + return OpenACCExitDataConstruct::Create(getASTContext(), StartLoc, DirLoc, + EndLoc, Clauses); + } + case OpenACCDirectiveKind::HostData: { + return OpenACCHostDataConstruct::Create( + getASTContext(), StartLoc, DirLoc, EndLoc, Clauses, + AssocStmt.isUsable() ? AssocStmt.get() : nullptr); + } } llvm_unreachable("Unhandled case in directive handling?"); } @@ -3230,9 +3695,15 @@ StmtResult SemaOpenACC::ActOnAssociatedStmt( switch (K) { default: llvm_unreachable("Unimplemented associated statement application"); + case OpenACCDirectiveKind::EnterData: + case OpenACCDirectiveKind::ExitData: + llvm_unreachable( + "these don't have associated statements, so shouldn't get here"); case OpenACCDirectiveKind::Parallel: case OpenACCDirectiveKind::Serial: case OpenACCDirectiveKind::Kernels: + case OpenACCDirectiveKind::Data: + case OpenACCDirectiveKind::HostData: // There really isn't any checking here that could happen. As long as we // have a statement to associate, this should be fine. // OpenACC 3.3 Section 6: diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index c174922a926fc..3dabe362802c9 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -15575,7 +15575,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE, // Build the actual expression node. ExprResult FnExpr = CreateFunctionRefExpr(*this, Method, FoundDecl, MemExpr, - HadMultipleCandidates, MemExpr->getBeginLoc()); + HadMultipleCandidates, MemExpr->getExprLoc()); if (FnExpr.isInvalid()) return ExprError(); diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 39f8ece62ed5c..c70ee73a2d8e1 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -2146,6 +2146,23 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl( // Check whether there is already a function template specialization for // this declaration. FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate(); + bool isFriend; + if (FunctionTemplate) + isFriend = (FunctionTemplate->getFriendObjectKind() != Decl::FOK_None); + else + isFriend = (D->getFriendObjectKind() != Decl::FOK_None); + + // Friend function defined withing class template may stop being function + // definition during AST merges from different modules, in this case decl + // with function body should be used for instantiation. + if (isFriend) { + const FunctionDecl *Defn = nullptr; + if (D->hasBody(Defn)) { + D = const_cast(Defn); + FunctionTemplate = Defn->getDescribedFunctionTemplate(); + } + } + if (FunctionTemplate && !TemplateParams) { ArrayRef Innermost = TemplateArgs.getInnermost(); @@ -2158,12 +2175,6 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl( return SpecFunc; } - bool isFriend; - if (FunctionTemplate) - isFriend = (FunctionTemplate->getFriendObjectKind() != Decl::FOK_None); - else - isFriend = (D->getFriendObjectKind() != Decl::FOK_None); - bool MergeWithParentScope = (TemplateParams != nullptr) || Owner->isFunctionOrMethod() || !(isa(Owner) && diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 5fb936297aa54..83464c50b4b23 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -2312,6 +2312,17 @@ QualType Sema::BuildArrayType(QualType T, ArraySizeModifier ASM, return T; } +static bool CheckBitIntElementType(Sema &S, SourceLocation AttrLoc, + const BitIntType *BIT, + bool ForMatrixType = false) { + // Only support _BitInt elements with byte-sized power of 2 NumBits. + unsigned NumBits = BIT->getNumBits(); + if (!llvm::isPowerOf2_32(NumBits) || NumBits < 8) + return S.Diag(AttrLoc, diag::err_attribute_invalid_bitint_vector_type) + << ForMatrixType << (NumBits < 8); + return false; +} + QualType Sema::BuildVectorType(QualType CurType, Expr *SizeExpr, SourceLocation AttrLoc) { // The base type must be integer (not Boolean or enumeration) or float, and @@ -2324,15 +2335,10 @@ QualType Sema::BuildVectorType(QualType CurType, Expr *SizeExpr, Diag(AttrLoc, diag::err_attribute_invalid_vector_type) << CurType; return QualType(); } - // Only support _BitInt elements with byte-sized power of 2 NumBits. - if (const auto *BIT = CurType->getAs()) { - unsigned NumBits = BIT->getNumBits(); - if (!llvm::isPowerOf2_32(NumBits) || NumBits < 8) { - Diag(AttrLoc, diag::err_attribute_invalid_bitint_vector_type) - << (NumBits < 8); - return QualType(); - } - } + + if (const auto *BIT = CurType->getAs(); + BIT && CheckBitIntElementType(*this, AttrLoc, BIT)) + return QualType(); if (SizeExpr->isTypeDependent() || SizeExpr->isValueDependent()) return Context.getDependentVectorType(CurType, SizeExpr, AttrLoc, @@ -2402,15 +2408,9 @@ QualType Sema::BuildExtVectorType(QualType T, Expr *ArraySize, return QualType(); } - // Only support _BitInt elements with byte-sized power of 2 NumBits. - if (T->isBitIntType()) { - unsigned NumBits = T->castAs()->getNumBits(); - if (!llvm::isPowerOf2_32(NumBits) || NumBits < 8) { - Diag(AttrLoc, diag::err_attribute_invalid_bitint_vector_type) - << (NumBits < 8); - return QualType(); - } - } + if (const auto *BIT = T->getAs(); + BIT && CheckBitIntElementType(*this, AttrLoc, BIT)) + return QualType(); if (!ArraySize->isTypeDependent() && !ArraySize->isValueDependent()) { std::optional vecSize = @@ -2455,6 +2455,11 @@ QualType Sema::BuildMatrixType(QualType ElementTy, Expr *NumRows, Expr *NumCols, return QualType(); } + if (const auto *BIT = ElementTy->getAs(); + BIT && + CheckBitIntElementType(*this, AttrLoc, BIT, /*ForMatrixType=*/true)) + return QualType(); + if (NumRows->isTypeDependent() || NumCols->isTypeDependent() || NumRows->isValueDependent() || NumCols->isValueDependent()) return Context.getDependentSizedMatrixType(ElementTy, NumRows, NumCols, @@ -5347,15 +5352,23 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state, case NestedNameSpecifier::TypeSpec: case NestedNameSpecifier::TypeSpecWithTemplate: - ClsType = QualType(NNS->getAsType(), 0); + const Type *NNSType = NNS->getAsType(); + ClsType = QualType(NNSType, 0); // Note: if the NNS has a prefix and ClsType is a nondependent - // TemplateSpecializationType, then the NNS prefix is NOT included - // in ClsType; hence we wrap ClsType into an ElaboratedType. - // NOTE: in particular, no wrap occurs if ClsType already is an - // Elaborated, DependentName, or DependentTemplateSpecialization. - if (isa(NNS->getAsType())) + // TemplateSpecializationType or a RecordType, then the NNS prefix is + // NOT included in ClsType; hence we wrap ClsType into an + // ElaboratedType. NOTE: in particular, no wrap occurs if ClsType + // already is an Elaborated, DependentName, or + // DependentTemplateSpecialization. + if (isa(NNSType)) { + // FIXME: Rebuild DependentTemplateSpecializationType, adding the + // Prefix. + } else if (isa(NNSType)) { + // Either the dependent case (TemplateSpecializationType), or the + // non-dependent one (RecordType). ClsType = Context.getElaboratedType(ElaboratedTypeKeyword::None, NNSPrefix, ClsType); + } break; } } else { diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 3a8f2d95f329b..04167e71d33f8 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -4110,6 +4110,42 @@ class TreeTransform { EndLoc, Clauses, Loop); } + StmtResult RebuildOpenACCDataConstruct(SourceLocation BeginLoc, + SourceLocation DirLoc, + SourceLocation EndLoc, + ArrayRef Clauses, + StmtResult StrBlock) { + return getSema().OpenACC().ActOnEndStmtDirective(OpenACCDirectiveKind::Data, + BeginLoc, DirLoc, EndLoc, + Clauses, StrBlock); + } + + StmtResult + RebuildOpenACCEnterDataConstruct(SourceLocation BeginLoc, + SourceLocation DirLoc, SourceLocation EndLoc, + ArrayRef Clauses) { + return getSema().OpenACC().ActOnEndStmtDirective( + OpenACCDirectiveKind::EnterData, BeginLoc, DirLoc, EndLoc, Clauses, {}); + } + + StmtResult + RebuildOpenACCExitDataConstruct(SourceLocation BeginLoc, + SourceLocation DirLoc, SourceLocation EndLoc, + ArrayRef Clauses) { + return getSema().OpenACC().ActOnEndStmtDirective( + OpenACCDirectiveKind::ExitData, BeginLoc, DirLoc, EndLoc, Clauses, {}); + } + + StmtResult RebuildOpenACCHostDataConstruct(SourceLocation BeginLoc, + SourceLocation DirLoc, + SourceLocation EndLoc, + ArrayRef Clauses, + StmtResult StrBlock) { + return getSema().OpenACC().ActOnEndStmtDirective( + OpenACCDirectiveKind::HostData, BeginLoc, DirLoc, EndLoc, Clauses, + StrBlock); + } + ExprResult RebuildOpenACCAsteriskSizeExpr(SourceLocation AsteriskLoc) { return getSema().OpenACC().ActOnOpenACCAsteriskSizeExpr(AsteriskLoc); } @@ -11719,6 +11755,50 @@ void OpenACCClauseTransform::VisitAttachClause( ParsedClause.getEndLoc()); } +template +void OpenACCClauseTransform::VisitDetachClause( + const OpenACCDetachClause &C) { + llvm::SmallVector VarList = VisitVarList(C.getVarList()); + + // Ensure each var is a pointer type. + VarList.erase( + std::remove_if(VarList.begin(), VarList.end(), + [&](Expr *E) { + return Self.getSema().OpenACC().CheckVarIsPointerType( + OpenACCClauseKind::Detach, E); + }), + VarList.end()); + + ParsedClause.setVarListDetails(VarList, + /*IsReadOnly=*/false, /*IsZero=*/false); + NewClause = OpenACCDetachClause::Create( + Self.getSema().getASTContext(), ParsedClause.getBeginLoc(), + ParsedClause.getLParenLoc(), ParsedClause.getVarList(), + ParsedClause.getEndLoc()); +} + +template +void OpenACCClauseTransform::VisitDeleteClause( + const OpenACCDeleteClause &C) { + ParsedClause.setVarListDetails(VisitVarList(C.getVarList()), + /*IsReadOnly=*/false, /*IsZero=*/false); + NewClause = OpenACCDeleteClause::Create( + Self.getSema().getASTContext(), ParsedClause.getBeginLoc(), + ParsedClause.getLParenLoc(), ParsedClause.getVarList(), + ParsedClause.getEndLoc()); +} + +template +void OpenACCClauseTransform::VisitUseDeviceClause( + const OpenACCUseDeviceClause &C) { + ParsedClause.setVarListDetails(VisitVarList(C.getVarList()), + /*IsReadOnly=*/false, /*IsZero=*/false); + NewClause = OpenACCUseDeviceClause::Create( + Self.getSema().getASTContext(), ParsedClause.getBeginLoc(), + ParsedClause.getLParenLoc(), ParsedClause.getVarList(), + ParsedClause.getEndLoc()); +} + template void OpenACCClauseTransform::VisitDevicePtrClause( const OpenACCDevicePtrClause &C) { @@ -11942,6 +12022,21 @@ void OpenACCClauseTransform::VisitSeqClause( ParsedClause.getBeginLoc(), ParsedClause.getEndLoc()); } +template +void OpenACCClauseTransform::VisitFinalizeClause( + const OpenACCFinalizeClause &C) { + NewClause = OpenACCFinalizeClause::Create(Self.getSema().getASTContext(), + ParsedClause.getBeginLoc(), + ParsedClause.getEndLoc()); +} + +template +void OpenACCClauseTransform::VisitIfPresentClause( + const OpenACCIfPresentClause &C) { + NewClause = OpenACCIfPresentClause::Create(Self.getSema().getASTContext(), + ParsedClause.getBeginLoc(), + ParsedClause.getEndLoc()); +} template void OpenACCClauseTransform::VisitReductionClause( @@ -12027,7 +12122,9 @@ void OpenACCClauseTransform::VisitGangClause( if (!ER.isUsable()) continue; - ER = Self.getSema().OpenACC().CheckGangExpr(C.getExpr(I).first, ER.get()); + ER = Self.getSema().OpenACC().CheckGangExpr(ExistingClauses, + ParsedClause.getDirectiveKind(), + C.getExpr(I).first, ER.get()); if (!ER.isUsable()) continue; TransformedGangKinds.push_back(C.getExpr(I).first); @@ -12035,7 +12132,8 @@ void OpenACCClauseTransform::VisitGangClause( } NewClause = Self.getSema().OpenACC().CheckGangClause( - ExistingClauses, ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(), + ParsedClause.getDirectiveKind(), ExistingClauses, + ParsedClause.getBeginLoc(), ParsedClause.getLParenLoc(), TransformedGangKinds, TransformedIntExprs, ParsedClause.getEndLoc()); } } // namespace @@ -12080,8 +12178,8 @@ StmtResult TreeTransform::TransformOpenACCComputeConstruct( getDerived().TransformOpenACCClauseList(C->getDirectiveKind(), C->clauses()); - if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(), - C->getBeginLoc())) + if (getSema().OpenACC().ActOnStartStmtDirective( + C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses)) return StmtError(); // Transform Structured Block. @@ -12107,8 +12205,8 @@ TreeTransform::TransformOpenACCLoopConstruct(OpenACCLoopConstruct *C) { getDerived().TransformOpenACCClauseList(C->getDirectiveKind(), C->clauses()); - if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(), - C->getBeginLoc())) + if (getSema().OpenACC().ActOnStartStmtDirective( + C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses)) return StmtError(); // Transform Loop. @@ -12133,8 +12231,8 @@ StmtResult TreeTransform::TransformOpenACCCombinedConstruct( getDerived().TransformOpenACCClauseList(C->getDirectiveKind(), C->clauses()); - if (getSema().OpenACC().ActOnStartStmtDirective(C->getDirectiveKind(), - C->getBeginLoc())) + if (getSema().OpenACC().ActOnStartStmtDirective( + C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses)) return StmtError(); // Transform Loop. @@ -12150,6 +12248,88 @@ StmtResult TreeTransform::TransformOpenACCCombinedConstruct( C->getEndLoc(), TransformedClauses, Loop); } +template +StmtResult +TreeTransform::TransformOpenACCDataConstruct(OpenACCDataConstruct *C) { + getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc()); + + llvm::SmallVector TransformedClauses = + getDerived().TransformOpenACCClauseList(C->getDirectiveKind(), + C->clauses()); + if (getSema().OpenACC().ActOnStartStmtDirective( + C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses)) + return StmtError(); + + SemaOpenACC::AssociatedStmtRAII AssocStmtRAII( + getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), + C->clauses(), TransformedClauses); + StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock()); + StrBlock = getSema().OpenACC().ActOnAssociatedStmt( + C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock); + + return getDerived().RebuildOpenACCDataConstruct( + C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(), + TransformedClauses, StrBlock); +} + +template +StmtResult TreeTransform::TransformOpenACCEnterDataConstruct( + OpenACCEnterDataConstruct *C) { + getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc()); + + llvm::SmallVector TransformedClauses = + getDerived().TransformOpenACCClauseList(C->getDirectiveKind(), + C->clauses()); + if (getSema().OpenACC().ActOnStartStmtDirective( + C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses)) + return StmtError(); + + return getDerived().RebuildOpenACCEnterDataConstruct( + C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(), + TransformedClauses); +} + +template +StmtResult TreeTransform::TransformOpenACCExitDataConstruct( + OpenACCExitDataConstruct *C) { + getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc()); + + llvm::SmallVector TransformedClauses = + getDerived().TransformOpenACCClauseList(C->getDirectiveKind(), + C->clauses()); + if (getSema().OpenACC().ActOnStartStmtDirective( + C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses)) + return StmtError(); + + return getDerived().RebuildOpenACCExitDataConstruct( + C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(), + TransformedClauses); +} + +template +StmtResult TreeTransform::TransformOpenACCHostDataConstruct( + OpenACCHostDataConstruct *C) { + getSema().OpenACC().ActOnConstruct(C->getDirectiveKind(), C->getBeginLoc()); + + llvm::SmallVector TransformedClauses = + getDerived().TransformOpenACCClauseList(C->getDirectiveKind(), + C->clauses()); + if (getSema().OpenACC().ActOnStartStmtDirective( + C->getDirectiveKind(), C->getBeginLoc(), TransformedClauses)) + return StmtError(); + + SemaOpenACC::AssociatedStmtRAII AssocStmtRAII( + getSema().OpenACC(), C->getDirectiveKind(), C->getDirectiveLoc(), + C->clauses(), TransformedClauses); + StmtResult StrBlock = getDerived().TransformStmt(C->getStructuredBlock()); + StrBlock = getSema().OpenACC().ActOnAssociatedStmt( + C->getBeginLoc(), C->getDirectiveKind(), TransformedClauses, StrBlock); + + return getDerived().RebuildOpenACCHostDataConstruct( + C->getBeginLoc(), C->getDirectiveLoc(), C->getEndLoc(), + TransformedClauses, StrBlock); +} + template ExprResult TreeTransform::TransformOpenACCAsteriskSizeExpr( OpenACCAsteriskSizeExpr *E) { diff --git a/clang/lib/Serialization/ASTCommon.h b/clang/lib/Serialization/ASTCommon.h index 2a765eafe0895..7c9ec884ea049 100644 --- a/clang/lib/Serialization/ASTCommon.h +++ b/clang/lib/Serialization/ASTCommon.h @@ -24,7 +24,6 @@ namespace serialization { enum DeclUpdateKind { UPD_CXX_ADDED_IMPLICIT_MEMBER, - UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, UPD_CXX_ADDED_ANONYMOUS_NAMESPACE, UPD_CXX_ADDED_FUNCTION_DEFINITION, UPD_CXX_ADDED_VAR_DEFINITION, diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index ec85fad3389a1..21f6b2ecc58c4 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -12,6 +12,7 @@ #include "ASTCommon.h" #include "ASTReaderInternals.h" +#include "TemplateArgumentHasher.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTMutationListener.h" @@ -1295,6 +1296,42 @@ void ASTDeclContextNameLookupTrait::ReadDataInto(internal_key_type, } } +ModuleFile * +LazySpecializationInfoLookupTrait::ReadFileRef(const unsigned char *&d) { + using namespace llvm::support; + + uint32_t ModuleFileID = + endian::readNext(d); + return Reader.getLocalModuleFile(F, ModuleFileID); +} + +LazySpecializationInfoLookupTrait::internal_key_type +LazySpecializationInfoLookupTrait::ReadKey(const unsigned char *d, unsigned) { + using namespace llvm::support; + return endian::readNext(d); +} + +std::pair +LazySpecializationInfoLookupTrait::ReadKeyDataLength(const unsigned char *&d) { + return readULEBKeyDataLength(d); +} + +void LazySpecializationInfoLookupTrait::ReadDataInto(internal_key_type, + const unsigned char *d, + unsigned DataLen, + data_type_builder &Val) { + using namespace llvm::support; + + for (unsigned NumDecls = + DataLen / sizeof(serialization::reader::LazySpecializationInfo); + NumDecls; --NumDecls) { + LocalDeclID LocalID = LocalDeclID::get( + Reader, F, + endian::readNext(d)); + Val.insert(Reader.getGlobalDeclID(F, LocalID)); + } +} + bool ASTReader::ReadLexicalDeclContextStorage(ModuleFile &M, BitstreamCursor &Cursor, uint64_t Offset, @@ -1379,7 +1416,52 @@ bool ASTReader::ReadVisibleDeclContextStorage(ModuleFile &M, // We can't safely determine the primary context yet, so delay attaching the // lookup table until we're done with recursive deserialization. auto *Data = (const unsigned char*)Blob.data(); - PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&M, Data}); + PendingVisibleUpdates[ID].push_back(UpdateData{&M, Data}); + return false; +} + +void ASTReader::AddSpecializations(const Decl *D, const unsigned char *Data, + ModuleFile &M, bool IsPartial) { + D = D->getCanonicalDecl(); + auto &SpecLookups = + IsPartial ? PartialSpecializationsLookups : SpecializationsLookups; + SpecLookups[D].Table.add(&M, Data, + reader::LazySpecializationInfoLookupTrait(*this, M)); +} + +bool ASTReader::ReadSpecializations(ModuleFile &M, BitstreamCursor &Cursor, + uint64_t Offset, Decl *D, bool IsPartial) { + assert(Offset != 0); + + SavedStreamPosition SavedPosition(Cursor); + if (llvm::Error Err = Cursor.JumpToBit(Offset)) { + Error(std::move(Err)); + return true; + } + + RecordData Record; + StringRef Blob; + Expected MaybeCode = Cursor.ReadCode(); + if (!MaybeCode) { + Error(MaybeCode.takeError()); + return true; + } + unsigned Code = MaybeCode.get(); + + Expected MaybeRecCode = Cursor.readRecord(Code, Record, &Blob); + if (!MaybeRecCode) { + Error(MaybeRecCode.takeError()); + return true; + } + unsigned RecCode = MaybeRecCode.get(); + if (RecCode != DECL_SPECIALIZATIONS && + RecCode != DECL_PARTIAL_SPECIALIZATIONS) { + Error("Expected decl specs block"); + return true; + } + + auto *Data = (const unsigned char *)Blob.data(); + AddSpecializations(D, Data, M, IsPartial); return false; } @@ -3458,7 +3540,33 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, unsigned Idx = 0; GlobalDeclID ID = ReadDeclID(F, Record, Idx); auto *Data = (const unsigned char*)Blob.data(); - PendingVisibleUpdates[ID].push_back(PendingVisibleUpdate{&F, Data}); + PendingVisibleUpdates[ID].push_back(UpdateData{&F, Data}); + // If we've already loaded the decl, perform the updates when we finish + // loading this block. + if (Decl *D = GetExistingDecl(ID)) + PendingUpdateRecords.push_back( + PendingUpdateRecord(ID, D, /*JustLoaded=*/false)); + break; + } + + case CXX_ADDED_TEMPLATE_SPECIALIZATION: { + unsigned Idx = 0; + GlobalDeclID ID = ReadDeclID(F, Record, Idx); + auto *Data = (const unsigned char *)Blob.data(); + PendingSpecializationsUpdates[ID].push_back(UpdateData{&F, Data}); + // If we've already loaded the decl, perform the updates when we finish + // loading this block. + if (Decl *D = GetExistingDecl(ID)) + PendingUpdateRecords.push_back( + PendingUpdateRecord(ID, D, /*JustLoaded=*/false)); + break; + } + + case CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION: { + unsigned Idx = 0; + GlobalDeclID ID = ReadDeclID(F, Record, Idx); + auto *Data = (const unsigned char *)Blob.data(); + PendingPartialSpecializationsUpdates[ID].push_back(UpdateData{&F, Data}); // If we've already loaded the decl, perform the updates when we finish // loading this block. if (Decl *D = GetExistingDecl(ID)) @@ -3855,14 +3963,14 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F, break; } - case FUNCTION_DECL_TO_LAMBDAS_MAP: + case RELATED_DECLS_MAP: for (unsigned I = 0, N = Record.size(); I != N; /*in loop*/) { GlobalDeclID ID = ReadDeclID(F, Record, I); - auto &Lambdas = FunctionToLambdasMap[ID]; + auto &RelatedDecls = RelatedDeclsMap[ID]; unsigned NN = Record[I++]; - Lambdas.reserve(NN); + RelatedDecls.reserve(NN); for (unsigned II = 0; II < NN; II++) - Lambdas.push_back(ReadDeclID(F, Record, I)); + RelatedDecls.push_back(ReadDeclID(F, Record, I)); } break; @@ -7654,13 +7762,28 @@ void ASTReader::CompleteRedeclChain(const Decl *D) { } } - if (auto *CTSD = dyn_cast(D)) - CTSD->getSpecializedTemplate()->LoadLazySpecializations(); - if (auto *VTSD = dyn_cast(D)) - VTSD->getSpecializedTemplate()->LoadLazySpecializations(); - if (auto *FD = dyn_cast(D)) { - if (auto *Template = FD->getPrimaryTemplate()) - Template->LoadLazySpecializations(); + RedeclarableTemplateDecl *Template = nullptr; + ArrayRef Args; + if (auto *CTSD = dyn_cast(D)) { + Template = CTSD->getSpecializedTemplate(); + Args = CTSD->getTemplateArgs().asArray(); + } else if (auto *VTSD = dyn_cast(D)) { + Template = VTSD->getSpecializedTemplate(); + Args = VTSD->getTemplateArgs().asArray(); + } else if (auto *FD = dyn_cast(D)) { + if (auto *Tmplt = FD->getPrimaryTemplate()) { + Template = Tmplt; + Args = FD->getTemplateSpecializationArgs()->asArray(); + } + } + + if (Template) { + // For partitial specialization, load all the specializations for safety. + if (isa(D)) + Template->loadLazySpecializationsImpl(); + else + Template->loadLazySpecializationsImpl(Args); } } @@ -8042,6 +8165,86 @@ Stmt *ASTReader::GetExternalDeclStmt(uint64_t Offset) { return ReadStmtFromStream(*Loc.F); } +bool ASTReader::LoadExternalSpecializationsImpl(SpecLookupTableTy &SpecLookups, + const Decl *D) { + assert(D); + + auto It = SpecLookups.find(D); + if (It == SpecLookups.end()) + return false; + + // Get Decl may violate the iterator from SpecializationsLookups so we store + // the DeclIDs in ahead. + llvm::SmallVector Infos = + It->second.Table.findAll(); + + // Since we've loaded all the specializations, we can erase it from + // the lookup table. + SpecLookups.erase(It); + + bool NewSpecsFound = false; + Deserializing LookupResults(this); + for (auto &Info : Infos) { + if (GetExistingDecl(Info)) + continue; + NewSpecsFound = true; + GetDecl(Info); + } + + return NewSpecsFound; +} + +bool ASTReader::LoadExternalSpecializations(const Decl *D, bool OnlyPartial) { + assert(D); + + bool NewSpecsFound = + LoadExternalSpecializationsImpl(PartialSpecializationsLookups, D); + if (OnlyPartial) + return NewSpecsFound; + + NewSpecsFound |= LoadExternalSpecializationsImpl(SpecializationsLookups, D); + return NewSpecsFound; +} + +bool ASTReader::LoadExternalSpecializationsImpl( + SpecLookupTableTy &SpecLookups, const Decl *D, + ArrayRef TemplateArgs) { + assert(D); + + auto It = SpecLookups.find(D); + if (It == SpecLookups.end()) + return false; + + Deserializing LookupResults(this); + auto HashValue = StableHashForTemplateArguments(TemplateArgs); + + // Get Decl may violate the iterator from SpecLookups + llvm::SmallVector Infos = + It->second.Table.find(HashValue); + + bool NewSpecsFound = false; + for (auto &Info : Infos) { + if (GetExistingDecl(Info)) + continue; + NewSpecsFound = true; + GetDecl(Info); + } + + return NewSpecsFound; +} + +bool ASTReader::LoadExternalSpecializations( + const Decl *D, ArrayRef TemplateArgs) { + assert(D); + + bool NewDeclsFound = LoadExternalSpecializationsImpl( + PartialSpecializationsLookups, D, TemplateArgs); + NewDeclsFound |= + LoadExternalSpecializationsImpl(SpecializationsLookups, D, TemplateArgs); + + return NewDeclsFound; +} + void ASTReader::FindExternalLexicalDecls( const DeclContext *DC, llvm::function_ref IsKindWeWant, SmallVectorImpl &Decls) { @@ -8221,6 +8424,22 @@ ASTReader::getLoadedLookupTables(DeclContext *Primary) const { return I == Lookups.end() ? nullptr : &I->second; } +serialization::reader::LazySpecializationInfoLookupTable * +ASTReader::getLoadedSpecializationsLookupTables(const Decl *D, bool IsPartial) { + assert(D->isCanonicalDecl()); + auto &LookupTable = + IsPartial ? PartialSpecializationsLookups : SpecializationsLookups; + auto I = LookupTable.find(D); + return I == LookupTable.end() ? nullptr : &I->second; +} + +bool ASTReader::haveUnloadedSpecializations(const Decl *D) const { + assert(D->isCanonicalDecl()); + return (PartialSpecializationsLookups.find(D) != + PartialSpecializationsLookups.end()) || + (SpecializationsLookups.find(D) != SpecializationsLookups.end()); +} + /// Under non-PCH compilation the consumer receives the objc methods /// before receiving the implementation, and codegen depends on this. /// We simulate this by deserializing and passing to consumer the methods of the @@ -10059,19 +10278,6 @@ void ASTReader::finishPendingActions() { PBEnd = PendingBodies.end(); PB != PBEnd; ++PB) { if (FunctionDecl *FD = dyn_cast(PB->first)) { - // For a function defined inline within a class template, force the - // canonical definition to be the one inside the canonical definition of - // the template. This ensures that we instantiate from a correct view - // of the template. - // - // Sadly we can't do this more generally: we can't be sure that all - // copies of an arbitrary class definition will have the same members - // defined (eg, some member functions may not be instantiated, and some - // special members may or may not have been implicitly defined). - if (auto *RD = dyn_cast(FD->getLexicalParent())) - if (RD->isDependentContext() && !RD->isThisDeclarationADefinition()) - continue; - // FIXME: Check for =delete/=default? const FunctionDecl *Defn = nullptr; if (!getContext().getLangOpts().Modules || !FD->hasBody(Defn)) { @@ -12223,6 +12429,24 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() { return OpenACCAttachClause::Create(getContext(), BeginLoc, LParenLoc, VarList, EndLoc); } + case OpenACCClauseKind::Detach: { + SourceLocation LParenLoc = readSourceLocation(); + llvm::SmallVector VarList = readOpenACCVarList(); + return OpenACCDetachClause::Create(getContext(), BeginLoc, LParenLoc, + VarList, EndLoc); + } + case OpenACCClauseKind::Delete: { + SourceLocation LParenLoc = readSourceLocation(); + llvm::SmallVector VarList = readOpenACCVarList(); + return OpenACCDeleteClause::Create(getContext(), BeginLoc, LParenLoc, + VarList, EndLoc); + } + case OpenACCClauseKind::UseDevice: { + SourceLocation LParenLoc = readSourceLocation(); + llvm::SmallVector VarList = readOpenACCVarList(); + return OpenACCUseDeviceClause::Create(getContext(), BeginLoc, LParenLoc, + VarList, EndLoc); + } case OpenACCClauseKind::DevicePtr: { SourceLocation LParenLoc = readSourceLocation(); llvm::SmallVector VarList = readOpenACCVarList(); @@ -12315,6 +12539,10 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() { } case OpenACCClauseKind::Seq: return OpenACCSeqClause::Create(getContext(), BeginLoc, EndLoc); + case OpenACCClauseKind::Finalize: + return OpenACCFinalizeClause::Create(getContext(), BeginLoc, EndLoc); + case OpenACCClauseKind::IfPresent: + return OpenACCIfPresentClause::Create(getContext(), BeginLoc, EndLoc); case OpenACCClauseKind::Independent: return OpenACCIndependentClause::Create(getContext(), BeginLoc, EndLoc); case OpenACCClauseKind::Auto: @@ -12360,12 +12588,7 @@ OpenACCClause *ASTRecordReader::readOpenACCClause() { VectorExpr, EndLoc); } - case OpenACCClauseKind::Finalize: - case OpenACCClauseKind::IfPresent: case OpenACCClauseKind::NoHost: - case OpenACCClauseKind::UseDevice: - case OpenACCClauseKind::Delete: - case OpenACCClauseKind::Detach: case OpenACCClauseKind::Device: case OpenACCClauseKind::DeviceResident: case OpenACCClauseKind::Host: diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 6ece3ba7af9f4..719bc0d06f5b1 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -187,11 +187,6 @@ class ASTDeclReader : public DeclVisitor { std::string readString() { return Record.readString(); } - void readDeclIDList(SmallVectorImpl &IDs) { - for (unsigned I = 0, Size = Record.readInt(); I != Size; ++I) - IDs.push_back(readDeclID()); - } - Decl *readDecl() { return Record.readDecl(); } template T *readDeclAs() { return Record.readDeclAs(); } @@ -284,30 +279,6 @@ class ASTDeclReader : public DeclVisitor { : Reader(Reader), MergeImpl(Reader), Record(Record), Loc(Loc), ThisDeclID(thisDeclID), ThisDeclLoc(ThisDeclLoc) {} - template - static void AddLazySpecializations(T *D, SmallVectorImpl &IDs) { - if (IDs.empty()) - return; - - // FIXME: We should avoid this pattern of getting the ASTContext. - ASTContext &C = D->getASTContext(); - - auto *&LazySpecializations = D->getCommonPtr()->LazySpecializations; - - if (auto &Old = LazySpecializations) { - IDs.insert(IDs.end(), Old + 1, Old + 1 + Old[0].getRawValue()); - llvm::sort(IDs); - IDs.erase(std::unique(IDs.begin(), IDs.end()), IDs.end()); - } - - auto *Result = new (C) GlobalDeclID[1 + IDs.size()]; - *Result = GlobalDeclID(IDs.size()); - - std::copy(IDs.begin(), IDs.end(), Result + 1); - - LazySpecializations = Result; - } - template static Decl *getMostRecentDeclImpl(Redeclarable *D); static Decl *getMostRecentDeclImpl(...); @@ -332,10 +303,13 @@ class ASTDeclReader : public DeclVisitor { static void markIncompleteDeclChainImpl(Redeclarable *D); static void markIncompleteDeclChainImpl(...); + void ReadSpecializations(ModuleFile &M, Decl *D, + llvm::BitstreamCursor &DeclsCursor, bool IsPartial); + void ReadFunctionDefinition(FunctionDecl *FD); void Visit(Decl *D); - void UpdateDecl(Decl *D, SmallVectorImpl &); + void UpdateDecl(Decl *D); static void setNextObjCCategory(ObjCCategoryDecl *Cat, ObjCCategoryDecl *Next) { @@ -2418,6 +2392,16 @@ void ASTDeclReader::VisitImplicitConceptSpecializationDecl( void ASTDeclReader::VisitRequiresExprBodyDecl(RequiresExprBodyDecl *D) { } +void ASTDeclReader::ReadSpecializations(ModuleFile &M, Decl *D, + llvm::BitstreamCursor &DeclsCursor, + bool IsPartial) { + uint64_t Offset = ReadLocalOffset(); + bool Failed = + Reader.ReadSpecializations(M, DeclsCursor, Offset, D, IsPartial); + (void)Failed; + assert(!Failed); +} + RedeclarableResult ASTDeclReader::VisitRedeclarableTemplateDecl(RedeclarableTemplateDecl *D) { RedeclarableResult Redecl = VisitRedeclarable(D); @@ -2456,9 +2440,8 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) { if (ThisDeclID == Redecl.getFirstID()) { // This ClassTemplateDecl owns a CommonPtr; read it to keep track of all of // the specializations. - SmallVector SpecIDs; - readDeclIDList(SpecIDs); - ASTDeclReader::AddLazySpecializations(D, SpecIDs); + ReadSpecializations(*Loc.F, D, Loc.F->DeclsCursor, /*IsPartial=*/false); + ReadSpecializations(*Loc.F, D, Loc.F->DeclsCursor, /*IsPartial=*/true); } if (D->getTemplatedDecl()->TemplateOrInstantiation) { @@ -2484,9 +2467,8 @@ void ASTDeclReader::VisitVarTemplateDecl(VarTemplateDecl *D) { if (ThisDeclID == Redecl.getFirstID()) { // This VarTemplateDecl owns a CommonPtr; read it to keep track of all of // the specializations. - SmallVector SpecIDs; - readDeclIDList(SpecIDs); - ASTDeclReader::AddLazySpecializations(D, SpecIDs); + ReadSpecializations(*Loc.F, D, Loc.F->DeclsCursor, /*IsPartial=*/false); + ReadSpecializations(*Loc.F, D, Loc.F->DeclsCursor, /*IsPartial=*/true); } } @@ -2585,9 +2567,7 @@ void ASTDeclReader::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { if (ThisDeclID == Redecl.getFirstID()) { // This FunctionTemplateDecl owns a CommonPtr; read it. - SmallVector SpecIDs; - readDeclIDList(SpecIDs); - ASTDeclReader::AddLazySpecializations(D, SpecIDs); + ReadSpecializations(*Loc.F, D, Loc.F->DeclsCursor, /*IsPartial=*/false); } } @@ -3877,6 +3857,8 @@ Decl *ASTReader::ReadDeclRecord(GlobalDeclID ID) { switch ((DeclCode)MaybeDeclCode.get()) { case DECL_CONTEXT_LEXICAL: case DECL_CONTEXT_VISIBLE: + case DECL_SPECIALIZATIONS: + case DECL_PARTIAL_SPECIALIZATIONS: llvm_unreachable("Record cannot be de-serialized with readDeclRecord"); case DECL_TYPEDEF: D = TypedefDecl::CreateDeserialized(Context, ID); @@ -4286,8 +4268,6 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) { ProcessingUpdatesRAIIObj ProcessingUpdates(*this); DeclUpdateOffsetsMap::iterator UpdI = DeclUpdateOffsets.find(ID); - SmallVector PendingLazySpecializationIDs; - if (UpdI != DeclUpdateOffsets.end()) { auto UpdateOffsets = std::move(UpdI->second); DeclUpdateOffsets.erase(UpdI); @@ -4324,7 +4304,7 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) { ASTDeclReader Reader(*this, Record, RecordLocation(F, Offset), ID, SourceLocation()); - Reader.UpdateDecl(D, PendingLazySpecializationIDs); + Reader.UpdateDecl(D); // We might have made this declaration interesting. If so, remember that // we need to hand it off to the consumer. @@ -4334,17 +4314,6 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) { } } } - // Add the lazy specializations to the template. - assert((PendingLazySpecializationIDs.empty() || isa(D) || - isa(D)) && - "Must not have pending specializations"); - if (auto *CTD = dyn_cast(D)) - ASTDeclReader::AddLazySpecializations(CTD, PendingLazySpecializationIDs); - else if (auto *FTD = dyn_cast(D)) - ASTDeclReader::AddLazySpecializations(FTD, PendingLazySpecializationIDs); - else if (auto *VTD = dyn_cast(D)) - ASTDeclReader::AddLazySpecializations(VTD, PendingLazySpecializationIDs); - PendingLazySpecializationIDs.clear(); // Load the pending visible updates for this decl context, if it has any. auto I = PendingVisibleUpdates.find(ID); @@ -4360,15 +4329,34 @@ void ASTReader::loadDeclUpdateRecords(PendingUpdateRecord &Record) { DC->setHasExternalVisibleStorage(true); } - // Load any pending lambdas for the function. - if (auto *FD = dyn_cast(D); FD && FD->isCanonicalDecl()) { - if (auto IT = FunctionToLambdasMap.find(ID); - IT != FunctionToLambdasMap.end()) { + // Load any pending related decls. + if (D->isCanonicalDecl()) { + if (auto IT = RelatedDeclsMap.find(ID); IT != RelatedDeclsMap.end()) { for (auto LID : IT->second) GetDecl(LID); - FunctionToLambdasMap.erase(IT); + RelatedDeclsMap.erase(IT); } } + + // Load the pending specializations update for this decl, if it has any. + if (auto I = PendingSpecializationsUpdates.find(ID); + I != PendingSpecializationsUpdates.end()) { + auto SpecializationUpdates = std::move(I->second); + PendingSpecializationsUpdates.erase(I); + + for (const auto &Update : SpecializationUpdates) + AddSpecializations(D, Update.Data, *Update.Mod, /*IsPartial=*/false); + } + + // Load the pending specializations update for this decl, if it has any. + if (auto I = PendingPartialSpecializationsUpdates.find(ID); + I != PendingPartialSpecializationsUpdates.end()) { + auto SpecializationUpdates = std::move(I->second); + PendingPartialSpecializationsUpdates.erase(I); + + for (const auto &Update : SpecializationUpdates) + AddSpecializations(D, Update.Data, *Update.Mod, /*IsPartial=*/true); + } } void ASTReader::loadPendingDeclChain(Decl *FirstLocal, uint64_t LocalOffset) { @@ -4561,9 +4549,7 @@ static void forAllLaterRedecls(DeclT *D, Fn F) { } } -void ASTDeclReader::UpdateDecl( - Decl *D, - llvm::SmallVectorImpl &PendingLazySpecializationIDs) { +void ASTDeclReader::UpdateDecl(Decl *D) { while (Record.getIdx() < Record.size()) { switch ((DeclUpdateKind)Record.readInt()) { case UPD_CXX_ADDED_IMPLICIT_MEMBER: { @@ -4574,11 +4560,6 @@ void ASTDeclReader::UpdateDecl( break; } - case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: - // It will be added to the template's lazy specialization set. - PendingLazySpecializationIDs.push_back(readDeclID()); - break; - case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: { auto *Anon = readDeclAs(); @@ -4616,7 +4597,7 @@ void ASTDeclReader::UpdateDecl( .dyn_cast()) FTSInfo->setPointOfInstantiation(POI); else - FD->TemplateOrSpecialization.get() + cast(FD->TemplateOrSpecialization) ->setPointOfInstantiation(POI); } break; @@ -4715,8 +4696,8 @@ void ASTDeclReader::UpdateDecl( // FIXME: If we already have a partial specialization set, // check that it matches. - if (!Spec->getSpecializedTemplateOrPartial() - .is()) + if (!isa( + Spec->getSpecializedTemplateOrPartial())) Spec->setInstantiationOf(PartialSpec, TemplArgList); } } diff --git a/clang/lib/Serialization/ASTReaderInternals.h b/clang/lib/Serialization/ASTReaderInternals.h index 4f7e6f4b2741b..be0d22d1f4094 100644 --- a/clang/lib/Serialization/ASTReaderInternals.h +++ b/clang/lib/Serialization/ASTReaderInternals.h @@ -119,6 +119,88 @@ struct DeclContextLookupTable { MultiOnDiskHashTable Table; }; +using LazySpecializationInfo = GlobalDeclID; + +/// Class that performs lookup to specialized decls. +class LazySpecializationInfoLookupTrait { + ASTReader &Reader; + ModuleFile &F; + +public: + // Maximum number of lookup tables we allow before condensing the tables. + static const int MaxTables = 4; + + /// The lookup result is a list of global declaration IDs. + using data_type = SmallVector; + + struct data_type_builder { + data_type &Data; + llvm::DenseSet Found; + + data_type_builder(data_type &D) : Data(D) {} + + void insert(LazySpecializationInfo Info) { + // Just use a linear scan unless we have more than a few IDs. + if (Found.empty() && !Data.empty()) { + if (Data.size() <= 4) { + for (auto I : Found) + if (I == Info) + return; + Data.push_back(Info); + return; + } + + // Switch to tracking found IDs in the set. + Found.insert(Data.begin(), Data.end()); + } + + if (Found.insert(Info).second) + Data.push_back(Info); + } + }; + using hash_value_type = unsigned; + using offset_type = unsigned; + using file_type = ModuleFile *; + + using external_key_type = unsigned; + using internal_key_type = unsigned; + + explicit LazySpecializationInfoLookupTrait(ASTReader &Reader, ModuleFile &F) + : Reader(Reader), F(F) {} + + static bool EqualKey(const internal_key_type &a, const internal_key_type &b) { + return a == b; + } + + static hash_value_type ComputeHash(const internal_key_type &Key) { + return Key; + } + + static internal_key_type GetInternalKey(const external_key_type &Name) { + return Name; + } + + static std::pair + ReadKeyDataLength(const unsigned char *&d); + + internal_key_type ReadKey(const unsigned char *d, unsigned); + + void ReadDataInto(internal_key_type, const unsigned char *d, unsigned DataLen, + data_type_builder &Val); + + static void MergeDataInto(const data_type &From, data_type_builder &To) { + To.Data.reserve(To.Data.size() + From.size()); + for (LazySpecializationInfo Info : From) + To.insert(Info); + } + + file_type ReadFileRef(const unsigned char *&d); +}; + +struct LazySpecializationInfoLookupTable { + MultiOnDiskHashTable Table; +}; + /// Base class for the trait describing the on-disk hash table for the /// identifiers in an AST file. /// diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp index 731ad0b64dc85..21ad6c5a9faa3 100644 --- a/clang/lib/Serialization/ASTReaderStmt.cpp +++ b/clang/lib/Serialization/ASTReaderStmt.cpp @@ -911,9 +911,9 @@ void ASTStmtReader::VisitRequiresExpr(RequiresExpr *E) { std::move(*Req), Status, SubstitutedConstraintExpr); else R = new (Record.getContext()) concepts::ExprRequirement( - E.get(), - RK == concepts::Requirement::RK_Simple, NoexceptLoc, - std::move(*Req)); + cast(E), + RK == concepts::Requirement::RK_Simple, NoexceptLoc, + std::move(*Req)); } break; case concepts::Requirement::RK_Nested: { ASTContext &C = Record.getContext(); @@ -2849,6 +2849,27 @@ void ASTStmtReader::VisitOpenACCCombinedConstruct(OpenACCCombinedConstruct *S) { VisitOpenACCAssociatedStmtConstruct(S); } +void ASTStmtReader::VisitOpenACCDataConstruct(OpenACCDataConstruct *S) { + VisitStmt(S); + VisitOpenACCAssociatedStmtConstruct(S); +} + +void ASTStmtReader::VisitOpenACCEnterDataConstruct( + OpenACCEnterDataConstruct *S) { + VisitStmt(S); + VisitOpenACCConstructStmt(S); +} + +void ASTStmtReader::VisitOpenACCExitDataConstruct(OpenACCExitDataConstruct *S) { + VisitStmt(S); + VisitOpenACCConstructStmt(S); +} + +void ASTStmtReader::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) { + VisitStmt(S); + VisitOpenACCAssociatedStmtConstruct(S); +} + //===----------------------------------------------------------------------===// // HLSL Constructs/Directives. //===----------------------------------------------------------------------===// @@ -4324,6 +4345,26 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) { S = OpenACCCombinedConstruct::CreateEmpty(Context, NumClauses); break; } + case STMT_OPENACC_DATA_CONSTRUCT: { + unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; + S = OpenACCDataConstruct::CreateEmpty(Context, NumClauses); + break; + } + case STMT_OPENACC_ENTER_DATA_CONSTRUCT: { + unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; + S = OpenACCEnterDataConstruct::CreateEmpty(Context, NumClauses); + break; + } + case STMT_OPENACC_EXIT_DATA_CONSTRUCT: { + unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; + S = OpenACCExitDataConstruct::CreateEmpty(Context, NumClauses); + break; + } + case STMT_OPENACC_HOST_DATA_CONSTRUCT: { + unsigned NumClauses = Record[ASTStmtReader::NumStmtFields]; + S = OpenACCHostDataConstruct::CreateEmpty(Context, NumClauses); + break; + } case EXPR_REQUIRES: { unsigned numLocalParameters = Record[ASTStmtReader::NumExprFields]; unsigned numRequirement = Record[ASTStmtReader::NumExprFields + 1]; diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index a52d59c61c4ce..6db2262a7952e 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -13,6 +13,7 @@ #include "ASTCommon.h" #include "ASTReaderInternals.h" #include "MultiOnDiskHashTable.h" +#include "TemplateArgumentHasher.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTUnresolvedSet.h" #include "clang/AST/AbstractTypeWriter.h" @@ -184,14 +185,30 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) { const SourceManager &SM = PP.getSourceManager(); const ModuleMap &MM = HS.getModuleMap(); - llvm::DenseSet ModuleMaps; - - llvm::DenseSet ProcessedModules; - auto CollectModuleMapsForHierarchy = [&](const Module *M) { + // Module maps used only by textual headers are special. Their FileID is + // non-affecting, but their FileEntry is (i.e. must be written as InputFile). + enum AffectedReason : bool { + AR_TextualHeader = 0, + AR_ImportOrTextualHeader = 1, + }; + auto AssignMostImportant = [](AffectedReason &LHS, AffectedReason RHS) { + LHS = std::max(LHS, RHS); + }; + llvm::DenseMap ModuleMaps; + llvm::DenseMap ProcessedModules; + auto CollectModuleMapsForHierarchy = [&](const Module *M, + AffectedReason Reason) { M = M->getTopLevelModule(); - if (!ProcessedModules.insert(M).second) + // We need to process the header either when it was not present or when we + // previously flagged module map as textual headers and now we found a + // proper import. + if (auto [It, Inserted] = ProcessedModules.insert({M, Reason}); + !Inserted && Reason <= It->second) { return; + } else { + It->second = Reason; + } std::queue Q; Q.push(M); @@ -202,12 +219,12 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) { // The containing module map is affecting, because it's being pointed // into by Module::DefinitionLoc. if (auto F = MM.getContainingModuleMapFileID(Mod); F.isValid()) - ModuleMaps.insert(F); + AssignMostImportant(ModuleMaps[F], Reason); // For inferred modules, the module map that allowed inferring is not // related to the virtual containing module map file. It did affect the // compilation, though. if (auto UniqF = MM.getModuleMapFileIDForUniquing(Mod); UniqF.isValid()) - ModuleMaps.insert(UniqF); + AssignMostImportant(ModuleMaps[UniqF], Reason); for (auto *SubM : Mod->submodules()) Q.push(SubM); @@ -216,7 +233,7 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) { // Handle all the affecting modules referenced from the root module. - CollectModuleMapsForHierarchy(RootModule); + CollectModuleMapsForHierarchy(RootModule, AR_ImportOrTextualHeader); std::queue Q; Q.push(RootModule); @@ -225,9 +242,9 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) { Q.pop(); for (const Module *ImportedModule : CurrentModule->Imports) - CollectModuleMapsForHierarchy(ImportedModule); + CollectModuleMapsForHierarchy(ImportedModule, AR_ImportOrTextualHeader); for (const Module *UndeclaredModule : CurrentModule->UndeclaredUses) - CollectModuleMapsForHierarchy(UndeclaredModule); + CollectModuleMapsForHierarchy(UndeclaredModule, AR_ImportOrTextualHeader); for (auto *M : CurrentModule->submodules()) Q.push(M); @@ -256,7 +273,7 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) { for (const auto &KH : HS.findResolvedModulesForHeader(*File)) if (const Module *M = KH.getModule()) - CollectModuleMapsForHierarchy(M); + CollectModuleMapsForHierarchy(M, AR_TextualHeader); } // FIXME: This algorithm is not correct for module map hierarchies where @@ -278,13 +295,16 @@ GetAffectingModuleMaps(const Preprocessor &PP, Module *RootModule) { // includes a module map defining a module that's not a submodule of X. llvm::DenseSet ModuleFileEntries; - for (FileID MM : ModuleMaps) { - if (auto *FE = SM.getFileEntryForID(MM)) + llvm::DenseSet ModuleFileIDs; + for (auto [FID, Reason] : ModuleMaps) { + if (Reason == AR_ImportOrTextualHeader) + ModuleFileIDs.insert(FID); + if (auto *FE = SM.getFileEntryForID(FID)) ModuleFileEntries.insert(FE); } AffectingModuleMaps R; - R.DefinitionFileIDs = std::move(ModuleMaps); + R.DefinitionFileIDs = std::move(ModuleFileIDs); R.DefinitionFiles = std::move(ModuleFileEntries); return std::move(R); } @@ -921,7 +941,7 @@ void ASTWriter::WriteBlockInfoBlock() { RECORD(PENDING_IMPLICIT_INSTANTIATIONS); RECORD(UPDATE_VISIBLE); RECORD(DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD); - RECORD(FUNCTION_DECL_TO_LAMBDAS_MAP); + RECORD(RELATED_DECLS_MAP); RECORD(DECL_UPDATE_OFFSETS); RECORD(DECL_UPDATES); RECORD(CUDA_SPECIAL_DECL_REFS); @@ -4148,6 +4168,175 @@ class ASTDeclContextNameLookupTrait { } // namespace +namespace { +class LazySpecializationInfoLookupTrait { + ASTWriter &Writer; + llvm::SmallVector Specs; + +public: + using key_type = unsigned; + using key_type_ref = key_type; + + /// A start and end index into Specs, representing a sequence of decls. + using data_type = std::pair; + using data_type_ref = const data_type &; + + using hash_value_type = unsigned; + using offset_type = unsigned; + + explicit LazySpecializationInfoLookupTrait(ASTWriter &Writer) + : Writer(Writer) {} + + template + data_type getData(Col &&C, Col2 &ExistingInfo) { + unsigned Start = Specs.size(); + for (auto *D : C) { + NamedDecl *ND = getDeclForLocalLookup(Writer.getLangOpts(), + const_cast(D)); + Specs.push_back(GlobalDeclID(Writer.GetDeclRef(ND).getRawValue())); + } + for (const serialization::reader::LazySpecializationInfo &Info : + ExistingInfo) + Specs.push_back(Info); + return std::make_pair(Start, Specs.size()); + } + + data_type ImportData( + const reader::LazySpecializationInfoLookupTrait::data_type &FromReader) { + unsigned Start = Specs.size(); + for (auto ID : FromReader) + Specs.push_back(ID); + return std::make_pair(Start, Specs.size()); + } + + static bool EqualKey(key_type_ref a, key_type_ref b) { return a == b; } + + hash_value_type ComputeHash(key_type Name) { return Name; } + + void EmitFileRef(raw_ostream &Out, ModuleFile *F) const { + assert(Writer.hasChain() && + "have reference to loaded module file but no chain?"); + + using namespace llvm::support; + endian::write(Out, Writer.getChain()->getModuleFileID(F), + llvm::endianness::little); + } + + std::pair EmitKeyDataLength(raw_ostream &Out, + key_type HashValue, + data_type_ref Lookup) { + // 4 bytes for each slot. + unsigned KeyLen = 4; + unsigned DataLen = sizeof(serialization::reader::LazySpecializationInfo) * + (Lookup.second - Lookup.first); + + return emitULEBKeyDataLength(KeyLen, DataLen, Out); + } + + void EmitKey(raw_ostream &Out, key_type HashValue, unsigned) { + using namespace llvm::support; + + endian::Writer LE(Out, llvm::endianness::little); + LE.write(HashValue); + } + + void EmitData(raw_ostream &Out, key_type_ref, data_type Lookup, + unsigned DataLen) { + using namespace llvm::support; + + endian::Writer LE(Out, llvm::endianness::little); + uint64_t Start = Out.tell(); + (void)Start; + for (unsigned I = Lookup.first, N = Lookup.second; I != N; ++I) { + LE.write(Specs[I].getRawValue()); + } + assert(Out.tell() - Start == DataLen && "Data length is wrong"); + } +}; + +unsigned CalculateODRHashForSpecs(const Decl *Spec) { + ArrayRef Args; + if (auto *CTSD = dyn_cast(Spec)) + Args = CTSD->getTemplateArgs().asArray(); + else if (auto *VTSD = dyn_cast(Spec)) + Args = VTSD->getTemplateArgs().asArray(); + else if (auto *FD = dyn_cast(Spec)) + Args = FD->getTemplateSpecializationArgs()->asArray(); + else + llvm_unreachable("New Specialization Kind?"); + + return StableHashForTemplateArguments(Args); +} +} // namespace + +void ASTWriter::GenerateSpecializationInfoLookupTable( + const NamedDecl *D, llvm::SmallVectorImpl &Specializations, + llvm::SmallVectorImpl &LookupTable, bool IsPartial) { + assert(D->isFirstDecl()); + + // Create the on-disk hash table representation. + MultiOnDiskHashTableGenerator + Generator; + LazySpecializationInfoLookupTrait Trait(*this); + + llvm::DenseMap> + SpecializationMaps; + + for (auto *Specialization : Specializations) { + unsigned HashedValue = CalculateODRHashForSpecs(Specialization); + + auto Iter = SpecializationMaps.find(HashedValue); + if (Iter == SpecializationMaps.end()) + Iter = SpecializationMaps + .try_emplace(HashedValue, + llvm::SmallVector()) + .first; + + Iter->second.push_back(cast(Specialization)); + } + + auto *Lookups = + Chain ? Chain->getLoadedSpecializationsLookupTables(D, IsPartial) + : nullptr; + + for (auto &[HashValue, Specs] : SpecializationMaps) { + SmallVector + ExisitingSpecs; + // We have to merge the lookup table manually here. We can't depend on the + // merge mechanism offered by + // clang::serialization::MultiOnDiskHashTableGenerator since that generator + // assumes the we'll get the same value with the same key. + // And also underlying llvm::OnDiskChainedHashTableGenerator assumes that we + // won't insert the values with the same key twice. So we have to merge the + // lookup table here manually. + if (Lookups) + ExisitingSpecs = Lookups->Table.find(HashValue); + + Generator.insert(HashValue, Trait.getData(Specs, ExisitingSpecs), Trait); + } + + Generator.emit(LookupTable, Trait, Lookups ? &Lookups->Table : nullptr); +} + +uint64_t ASTWriter::WriteSpecializationInfoLookupTable( + const NamedDecl *D, llvm::SmallVectorImpl &Specializations, + bool IsPartial) { + + llvm::SmallString<4096> LookupTable; + GenerateSpecializationInfoLookupTable(D, Specializations, LookupTable, + IsPartial); + + uint64_t Offset = Stream.GetCurrentBitNo(); + RecordData::value_type Record[] = {static_cast( + IsPartial ? DECL_PARTIAL_SPECIALIZATIONS : DECL_SPECIALIZATIONS)}; + Stream.EmitRecordWithBlob(IsPartial ? DeclPartialSpecializationsAbbrev + : DeclSpecializationsAbbrev, + Record, LookupTable); + + return Offset; +} + bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result, DeclContext *DC) { return Result.hasExternalDecls() && @@ -4922,7 +5111,7 @@ ASTWriter::WriteAST(llvm::PointerUnion Subject, Sema *SemaPtr = Subject.dyn_cast(); Preprocessor &PPRef = - SemaPtr ? SemaPtr->getPreprocessor() : *Subject.get(); + SemaPtr ? SemaPtr->getPreprocessor() : *cast(Subject); ASTHasCompilerErrors = PPRef.getDiagnostics().hasUncompilableErrorOccurred(); @@ -5729,7 +5918,7 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { // Keep writing types, declarations, and declaration update records // until we've emitted all of them. RecordData DeclUpdatesOffsetsRecord; - Stream.EnterSubblock(DECLTYPES_BLOCK_ID, /*bits for abbreviations*/5); + Stream.EnterSubblock(DECLTYPES_BLOCK_ID, /*bits for abbreviations*/ 6); DeclTypesBlockStartOffset = Stream.GetCurrentBitNo(); WriteTypeAbbrevs(); WriteDeclAbbrevs(); @@ -5783,26 +5972,36 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { Stream.EmitRecord(DELAYED_NAMESPACE_LEXICAL_VISIBLE_RECORD, DelayedNamespaceRecord); - if (!FunctionToLambdasMap.empty()) { - // TODO: on disk hash table for function to lambda mapping might be more + if (!RelatedDeclsMap.empty()) { + // TODO: on disk hash table for related decls mapping might be more // efficent becuase it allows lazy deserialization. - RecordData FunctionToLambdasMapRecord; - for (const auto &Pair : FunctionToLambdasMap) { - FunctionToLambdasMapRecord.push_back(Pair.first.getRawValue()); - FunctionToLambdasMapRecord.push_back(Pair.second.size()); + RecordData RelatedDeclsMapRecord; + for (const auto &Pair : RelatedDeclsMap) { + RelatedDeclsMapRecord.push_back(Pair.first.getRawValue()); + RelatedDeclsMapRecord.push_back(Pair.second.size()); for (const auto &Lambda : Pair.second) - FunctionToLambdasMapRecord.push_back(Lambda.getRawValue()); + RelatedDeclsMapRecord.push_back(Lambda.getRawValue()); } auto Abv = std::make_shared(); - Abv->Add(llvm::BitCodeAbbrevOp(FUNCTION_DECL_TO_LAMBDAS_MAP)); + Abv->Add(llvm::BitCodeAbbrevOp(RELATED_DECLS_MAP)); Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Array)); Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); unsigned FunctionToLambdaMapAbbrev = Stream.EmitAbbrev(std::move(Abv)); - Stream.EmitRecord(FUNCTION_DECL_TO_LAMBDAS_MAP, FunctionToLambdasMapRecord, + Stream.EmitRecord(RELATED_DECLS_MAP, RelatedDeclsMapRecord, FunctionToLambdaMapAbbrev); } + if (!SpecializationsUpdates.empty()) { + WriteSpecializationsUpdates(/*IsPartial=*/false); + SpecializationsUpdates.clear(); + } + + if (!PartialSpecializationsUpdates.empty()) { + WriteSpecializationsUpdates(/*IsPartial=*/true); + PartialSpecializationsUpdates.clear(); + } + const TranslationUnitDecl *TU = Context.getTranslationUnitDecl(); // Create a lexical update block containing all of the declarations in the // translation unit that do not come from other AST files. @@ -5846,6 +6045,33 @@ void ASTWriter::WriteDeclAndTypes(ASTContext &Context) { WriteDeclContextVisibleUpdate(Context, DC); } +void ASTWriter::WriteSpecializationsUpdates(bool IsPartial) { + auto RecordType = IsPartial ? CXX_ADDED_TEMPLATE_PARTIAL_SPECIALIZATION + : CXX_ADDED_TEMPLATE_SPECIALIZATION; + + auto Abv = std::make_shared(); + Abv->Add(llvm::BitCodeAbbrevOp(RecordType)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::VBR, 6)); + Abv->Add(llvm::BitCodeAbbrevOp(llvm::BitCodeAbbrevOp::Blob)); + auto UpdateSpecializationAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + auto &SpecUpdates = + IsPartial ? PartialSpecializationsUpdates : SpecializationsUpdates; + for (auto &SpecializationUpdate : SpecUpdates) { + const NamedDecl *D = SpecializationUpdate.first; + + llvm::SmallString<4096> LookupTable; + GenerateSpecializationInfoLookupTable(D, SpecializationUpdate.second, + LookupTable, IsPartial); + + // Write the lookup table + RecordData::value_type Record[] = { + static_cast(RecordType), + getDeclID(D).getRawValue()}; + Stream.EmitRecordWithBlob(UpdateSpecializationAbbrev, Record, LookupTable); + } +} + void ASTWriter::WriteDeclUpdatesBlocks(ASTContext &Context, RecordDataImpl &OffsetsRecord) { if (DeclUpdates.empty()) @@ -5875,12 +6101,10 @@ void ASTWriter::WriteDeclUpdatesBlocks(ASTContext &Context, switch (Kind) { case UPD_CXX_ADDED_IMPLICIT_MEMBER: - case UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION: case UPD_CXX_ADDED_ANONYMOUS_NAMESPACE: assert(Update.getDecl() && "no decl to add?"); Record.AddDeclRef(Update.getDecl()); break; - case UPD_CXX_ADDED_FUNCTION_DEFINITION: case UPD_CXX_ADDED_VAR_DEFINITION: break; @@ -8132,6 +8356,24 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) { writeOpenACCVarList(AC); return; } + case OpenACCClauseKind::Detach: { + const auto *DC = cast(C); + writeSourceLocation(DC->getLParenLoc()); + writeOpenACCVarList(DC); + return; + } + case OpenACCClauseKind::Delete: { + const auto *DC = cast(C); + writeSourceLocation(DC->getLParenLoc()); + writeOpenACCVarList(DC); + return; + } + case OpenACCClauseKind::UseDevice: { + const auto *UDC = cast(C); + writeSourceLocation(UDC->getLParenLoc()); + writeOpenACCVarList(UDC); + return; + } case OpenACCClauseKind::DevicePtr: { const auto *DPC = cast(C); writeSourceLocation(DPC->getLParenLoc()); @@ -8227,6 +8469,8 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) { case OpenACCClauseKind::Seq: case OpenACCClauseKind::Independent: case OpenACCClauseKind::Auto: + case OpenACCClauseKind::Finalize: + case OpenACCClauseKind::IfPresent: // Nothing to do here, there is no additional information beyond the // begin/end loc and clause kind. return; @@ -8272,12 +8516,7 @@ void ASTRecordWriter::writeOpenACCClause(const OpenACCClause *C) { return; } - case OpenACCClauseKind::Finalize: - case OpenACCClauseKind::IfPresent: case OpenACCClauseKind::NoHost: - case OpenACCClauseKind::UseDevice: - case OpenACCClauseKind::Delete: - case OpenACCClauseKind::Detach: case OpenACCClauseKind::Device: case OpenACCClauseKind::DeviceResident: case OpenACCClauseKind::Host: diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp index ad357e30d5752..75c1d9a6d438c 100644 --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -177,11 +177,12 @@ namespace clang { Record.AddSourceLocation(typeParams->getRAngleLoc()); } - /// Add to the record the first declaration from each module file that - /// provides a declaration of D. The intent is to provide a sufficient - /// set such that reloading this set will load all current redeclarations. - void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) { - llvm::MapVector Firsts; + /// Collect the first declaration from each module file that provides a + /// declaration of D. + void CollectFirstDeclFromEachModule( + const Decl *D, bool IncludeLocal, + llvm::MapVector &Firsts) { + // FIXME: We can skip entries that we know are implied by others. for (const Decl *R = D->getMostRecentDecl(); R; R = R->getPreviousDecl()) { if (R->isFromASTFile()) @@ -189,10 +190,41 @@ namespace clang { else if (IncludeLocal) Firsts[nullptr] = R; } + } + + /// Add to the record the first declaration from each module file that + /// provides a declaration of D. The intent is to provide a sufficient + /// set such that reloading this set will load all current redeclarations. + void AddFirstDeclFromEachModule(const Decl *D, bool IncludeLocal) { + llvm::MapVector Firsts; + CollectFirstDeclFromEachModule(D, IncludeLocal, Firsts); + for (const auto &F : Firsts) Record.AddDeclRef(F.second); } + /// Add to the record the first template specialization from each module + /// file that provides a declaration of D. We store the DeclId and an + /// ODRHash of the template arguments of D which should provide enough + /// information to load D only if the template instantiator needs it. + void AddFirstSpecializationDeclFromEachModule( + const Decl *D, llvm::SmallVectorImpl &SpecsInMap, + llvm::SmallVectorImpl &PartialSpecsInMap) { + assert((isa(D) || + isa(D) || isa(D)) && + "Must not be called with other decls"); + llvm::MapVector Firsts; + CollectFirstDeclFromEachModule(D, /*IncludeLocal*/ true, Firsts); + + for (const auto &F : Firsts) { + if (isa(F.second)) + PartialSpecsInMap.push_back(F.second); + else + SpecsInMap.push_back(F.second); + } + } + /// Get the specialization decl from an entry in the specialization list. template typename RedeclarableTemplateDecl::SpecEntryTraits::DeclType * @@ -205,8 +237,9 @@ namespace clang { decltype(T::PartialSpecializations) &getPartialSpecializations(T *Common) { return Common->PartialSpecializations; } - ArrayRef getPartialSpecializations(FunctionTemplateDecl::Common *) { - return {}; + MutableArrayRef + getPartialSpecializations(FunctionTemplateDecl::Common *) { + return std::nullopt; } template @@ -217,37 +250,37 @@ namespace clang { // our chained AST reader, we can just write out the DeclIDs. Otherwise, // we need to resolve them to actual declarations. if (Writer.Chain != Record.getASTContext().getExternalSource() && - Common->LazySpecializations) { + Writer.Chain && Writer.Chain->haveUnloadedSpecializations(D)) { D->LoadLazySpecializations(); - assert(!Common->LazySpecializations); + assert(!Writer.Chain->haveUnloadedSpecializations(D)); } - ArrayRef LazySpecializations; - if (auto *LS = Common->LazySpecializations) - LazySpecializations = llvm::ArrayRef(LS + 1, LS[0].getRawValue()); - - // Add a slot to the record for the number of specializations. - unsigned I = Record.size(); - Record.push_back(0); - - // AddFirstDeclFromEachModule might trigger deserialization, invalidating - // *Specializations iterators. - llvm::SmallVector Specs; + // AddFirstSpecializationDeclFromEachModule might trigger deserialization, + // invalidating *Specializations iterators. + llvm::SmallVector AllSpecs; for (auto &Entry : Common->Specializations) - Specs.push_back(getSpecializationDecl(Entry)); + AllSpecs.push_back(getSpecializationDecl(Entry)); for (auto &Entry : getPartialSpecializations(Common)) - Specs.push_back(getSpecializationDecl(Entry)); + AllSpecs.push_back(getSpecializationDecl(Entry)); - for (auto *D : Specs) { + llvm::SmallVector Specs; + llvm::SmallVector PartialSpecs; + for (auto *D : AllSpecs) { assert(D->isCanonicalDecl() && "non-canonical decl in set"); - AddFirstDeclFromEachModule(D, /*IncludeLocal*/true); + AddFirstSpecializationDeclFromEachModule(D, Specs, PartialSpecs); + } + + Record.AddOffset(Writer.WriteSpecializationInfoLookupTable( + D, Specs, /*IsPartial=*/false)); + + // Function Template Decl doesn't have partial decls. + if (isa(D)) { + assert(PartialSpecs.empty()); + return; } - Record.append( - DeclIDIterator(LazySpecializations.begin()), - DeclIDIterator(LazySpecializations.end())); - // Update the size entry we added earlier. - Record[I] = Record.size() - I - 1; + Record.AddOffset(Writer.WriteSpecializationInfoLookupTable( + D, PartialSpecs, /*IsPartial=*/true)); } /// Ensure that this template specialization is associated with the specified @@ -268,8 +301,13 @@ namespace clang { if (Writer.getFirstLocalDecl(Specialization) != Specialization) return; - Writer.DeclUpdates[Template].push_back(ASTWriter::DeclUpdate( - UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION, Specialization)); + if (isa(Specialization)) + Writer.PartialSpecializationsUpdates[cast(Template)] + .push_back(cast(Specialization)); + else + Writer.SpecializationsUpdates[cast(Template)].push_back( + cast(Specialization)); } }; } @@ -760,6 +798,17 @@ void ASTDeclWriter::VisitFunctionDecl(FunctionDecl *D) { } } + if (D->getFriendObjectKind()) { + // For a function defined inline within a class template, we have to force + // the canonical definition to be the one inside the canonical definition of + // the template. Remember this relation to deserialize them together. + if (auto *RD = dyn_cast(D->getLexicalParent())) + if (RD->isDependentContext() && RD->isThisDeclarationADefinition()) { + Writer.RelatedDeclsMap[Writer.GetDeclRef(RD)].push_back( + Writer.GetDeclRef(D)); + } + } + Record.push_back(D->param_size()); for (auto *P : D->parameters()) Record.AddDeclRef(P); @@ -1525,7 +1574,7 @@ void ASTDeclWriter::VisitCXXRecordDecl(CXXRecordDecl *D) { // For lambdas inside canonical FunctionDecl remember the mapping. if (auto FD = llvm::dyn_cast_or_null(D->getDeclContext()); FD && FD->isCanonicalDecl()) { - Writer.FunctionToLambdasMap[Writer.GetDeclRef(FD)].push_back( + Writer.RelatedDeclsMap[Writer.GetDeclRef(FD)].push_back( Writer.GetDeclRef(D)); } } else { @@ -1656,7 +1705,7 @@ void ASTDeclWriter::VisitFriendDecl(FriendDecl *D) { // so as to simplify memory allocation during deserialization. Record.push_back(D->NumTPLists); VisitDecl(D); - bool hasFriendDecl = D->Friend.is(); + bool hasFriendDecl = isa(D->Friend); Record.push_back(hasFriendDecl); if (hasFriendDecl) Record.AddDeclRef(D->getFriendDecl()); @@ -1757,7 +1806,7 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl( if (Decl *InstFromD = InstFrom.dyn_cast()) { Record.AddDeclRef(InstFromD); } else { - Record.AddDeclRef(InstFrom.get()); + Record.AddDeclRef(cast(InstFrom)); Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs()); } @@ -1835,7 +1884,7 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl( if (Decl *InstFromD = InstFrom.dyn_cast()) { Record.AddDeclRef(InstFromD); } else { - Record.AddDeclRef(InstFrom.get()); + Record.AddDeclRef(cast(InstFrom)); Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs()); } @@ -2774,6 +2823,16 @@ void ASTWriter::WriteDeclAbbrevs() { Abv->Add(BitCodeAbbrevOp(serialization::DECL_CONTEXT_VISIBLE)); Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); DeclContextVisibleLookupAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::DECL_SPECIALIZATIONS)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); + DeclSpecializationsAbbrev = Stream.EmitAbbrev(std::move(Abv)); + + Abv = std::make_shared(); + Abv->Add(BitCodeAbbrevOp(serialization::DECL_PARTIAL_SPECIALIZATIONS)); + Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); + DeclPartialSpecializationsAbbrev = Stream.EmitAbbrev(std::move(Abv)); } /// isRequiredDecl - Check if this is a "required" Decl, which must be seen by diff --git a/clang/lib/Serialization/ASTWriterStmt.cpp b/clang/lib/Serialization/ASTWriterStmt.cpp index 4994047d9fe10..e55cbe1f6ecce 100644 --- a/clang/lib/Serialization/ASTWriterStmt.cpp +++ b/clang/lib/Serialization/ASTWriterStmt.cpp @@ -480,7 +480,7 @@ addConstraintSatisfaction(ASTRecordWriter &Record, if (E) Record.AddStmt(E); else { - auto *Diag = DetailRecord.get *>(); + auto *Diag = cast *>(DetailRecord); Record.AddSourceLocation(Diag->first); Record.AddString(Diag->second); } @@ -532,10 +532,11 @@ void ASTStmtWriter::VisitRequiresExpr(RequiresExpr *E) { Record.push_back(ExprReq->getKind()); Record.push_back(ExprReq->Status); if (ExprReq->isExprSubstitutionFailure()) { - addSubstitutionDiagnostic(Record, - ExprReq->Value.get()); + addSubstitutionDiagnostic( + Record, cast( + ExprReq->Value)); } else - Record.AddStmt(ExprReq->Value.get()); + Record.AddStmt(cast(ExprReq->Value)); if (ExprReq->getKind() == concepts::Requirement::RK_Compound) { Record.AddSourceLocation(ExprReq->NoexceptLoc); const auto &RetReq = ExprReq->getReturnTypeRequirement(); @@ -1166,7 +1167,7 @@ void ASTStmtWriter::VisitInitListExpr(InitListExpr *E) { Record.AddStmt(E->getSyntacticForm()); Record.AddSourceLocation(E->getLBraceLoc()); Record.AddSourceLocation(E->getRBraceLoc()); - bool isArrayFiller = E->ArrayFillerOrUnionFieldInit.is(); + bool isArrayFiller = isa(E->ArrayFillerOrUnionFieldInit); Record.push_back(isArrayFiller); if (isArrayFiller) Record.AddStmt(E->getArrayFiller()); @@ -2925,6 +2926,31 @@ void ASTStmtWriter::VisitOpenACCCombinedConstruct(OpenACCCombinedConstruct *S) { Code = serialization::STMT_OPENACC_COMBINED_CONSTRUCT; } +void ASTStmtWriter::VisitOpenACCDataConstruct(OpenACCDataConstruct *S) { + VisitStmt(S); + VisitOpenACCAssociatedStmtConstruct(S); + Code = serialization::STMT_OPENACC_DATA_CONSTRUCT; +} + +void ASTStmtWriter::VisitOpenACCEnterDataConstruct( + OpenACCEnterDataConstruct *S) { + VisitStmt(S); + VisitOpenACCConstructStmt(S); + Code = serialization::STMT_OPENACC_ENTER_DATA_CONSTRUCT; +} + +void ASTStmtWriter::VisitOpenACCExitDataConstruct(OpenACCExitDataConstruct *S) { + VisitStmt(S); + VisitOpenACCConstructStmt(S); + Code = serialization::STMT_OPENACC_EXIT_DATA_CONSTRUCT; +} + +void ASTStmtWriter::VisitOpenACCHostDataConstruct(OpenACCHostDataConstruct *S) { + VisitStmt(S); + VisitOpenACCAssociatedStmtConstruct(S); + Code = serialization::STMT_OPENACC_HOST_DATA_CONSTRUCT; +} + //===----------------------------------------------------------------------===// // HLSL Constructs/Directives. //===----------------------------------------------------------------------===// diff --git a/clang/lib/Serialization/CMakeLists.txt b/clang/lib/Serialization/CMakeLists.txt index 99c47c15a2f47..b1fc0345047f2 100644 --- a/clang/lib/Serialization/CMakeLists.txt +++ b/clang/lib/Serialization/CMakeLists.txt @@ -23,6 +23,7 @@ add_clang_library(clangSerialization ModuleManager.cpp PCHContainerOperations.cpp ObjectFilePCHContainerReader.cpp + TemplateArgumentHasher.cpp ADDITIONAL_HEADERS ASTCommon.h diff --git a/clang/lib/Serialization/TemplateArgumentHasher.cpp b/clang/lib/Serialization/TemplateArgumentHasher.cpp new file mode 100644 index 0000000000000..598f098f526d0 --- /dev/null +++ b/clang/lib/Serialization/TemplateArgumentHasher.cpp @@ -0,0 +1,409 @@ +//===- TemplateArgumentHasher.cpp - Hash Template Arguments -----*- 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 "TemplateArgumentHasher.h" +#include "clang/AST/APValue.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclTemplate.h" +#include "clang/AST/DeclarationName.h" +#include "clang/AST/TypeVisitor.h" +#include "clang/Basic/IdentifierTable.h" +#include "llvm/ADT/FoldingSet.h" + +using namespace clang; + +namespace { + +class TemplateArgumentHasher { + // If we bail out during the process of calculating hash values for + // template arguments for any reason. We're allowed to do it since + // TemplateArgumentHasher are only required to give the same hash value + // for the same template arguments, but not required to give different + // hash value for different template arguments. + // + // So in the worst case, it is still a valid implementation to give all + // inputs the same BailedOutValue as output. + bool BailedOut = false; + static constexpr unsigned BailedOutValue = 0x12345678; + + llvm::FoldingSetNodeID ID; + +public: + TemplateArgumentHasher() = default; + + void AddTemplateArgument(TemplateArgument TA); + + void AddInteger(unsigned V) { ID.AddInteger(V); } + + unsigned getValue() { + if (BailedOut) + return BailedOutValue; + + return ID.computeStableHash(); + } + + void setBailedOut() { BailedOut = true; } + + void AddType(const Type *T); + void AddQualType(QualType T); + void AddDecl(const Decl *D); + void AddStructuralValue(const APValue &); + void AddTemplateName(TemplateName Name); + void AddDeclarationName(DeclarationName Name); + void AddIdentifierInfo(const IdentifierInfo *II); +}; + +void TemplateArgumentHasher::AddTemplateArgument(TemplateArgument TA) { + const auto Kind = TA.getKind(); + AddInteger(Kind); + + switch (Kind) { + case TemplateArgument::Null: + llvm_unreachable("Expected valid TemplateArgument"); + case TemplateArgument::Type: + AddQualType(TA.getAsType()); + break; + case TemplateArgument::Declaration: + AddDecl(TA.getAsDecl()); + break; + case TemplateArgument::NullPtr: + ID.AddPointer(nullptr); + break; + case TemplateArgument::Integral: { + // There are integrals (e.g.: _BitInt(128)) that cannot be represented as + // any builtin integral type, so we use the hash of APSInt instead. + TA.getAsIntegral().Profile(ID); + break; + } + case TemplateArgument::StructuralValue: + AddQualType(TA.getStructuralValueType()); + AddStructuralValue(TA.getAsStructuralValue()); + break; + case TemplateArgument::Template: + case TemplateArgument::TemplateExpansion: + AddTemplateName(TA.getAsTemplateOrTemplatePattern()); + break; + case TemplateArgument::Expression: + // If we meet expression in template argument, it implies + // that the template is still dependent. It is meaningless + // to get a stable hash for the template. Bail out simply. + BailedOut = true; + break; + case TemplateArgument::Pack: + AddInteger(TA.pack_size()); + for (auto SubTA : TA.pack_elements()) { + AddTemplateArgument(SubTA); + } + break; + } +} + +void TemplateArgumentHasher::AddStructuralValue(const APValue &Value) { + auto Kind = Value.getKind(); + AddInteger(Kind); + + // 'APValue::Profile' uses pointer values to make hash for LValue and + // MemberPointer, but they differ from one compiler invocation to another. + // It may be difficult to handle such cases. Bail out simply. + + if (Kind == APValue::LValue || Kind == APValue::MemberPointer) { + BailedOut = true; + return; + } + + Value.Profile(ID); +} + +void TemplateArgumentHasher::AddTemplateName(TemplateName Name) { + switch (Name.getKind()) { + case TemplateName::Template: + AddDecl(Name.getAsTemplateDecl()); + break; + case TemplateName::QualifiedTemplate: { + QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName(); + AddTemplateName(QTN->getUnderlyingTemplate()); + break; + } + case TemplateName::OverloadedTemplate: + case TemplateName::AssumedTemplate: + case TemplateName::DependentTemplate: + case TemplateName::SubstTemplateTemplateParm: + case TemplateName::SubstTemplateTemplateParmPack: + BailedOut = true; + break; + case TemplateName::UsingTemplate: { + UsingShadowDecl *USD = Name.getAsUsingShadowDecl(); + if (USD) + AddDecl(USD->getTargetDecl()); + else + BailedOut = true; + break; + } + case TemplateName::DeducedTemplate: + AddTemplateName(Name.getAsDeducedTemplateName()->getUnderlying()); + break; + } +} + +void TemplateArgumentHasher::AddIdentifierInfo(const IdentifierInfo *II) { + assert(II && "Expecting non-null pointer."); + ID.AddString(II->getName()); +} + +void TemplateArgumentHasher::AddDeclarationName(DeclarationName Name) { + if (Name.isEmpty()) + return; + + switch (Name.getNameKind()) { + case DeclarationName::Identifier: + AddIdentifierInfo(Name.getAsIdentifierInfo()); + break; + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + BailedOut = true; + break; + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + AddQualType(Name.getCXXNameType()); + break; + case DeclarationName::CXXOperatorName: + AddInteger(Name.getCXXOverloadedOperator()); + break; + case DeclarationName::CXXLiteralOperatorName: + AddIdentifierInfo(Name.getCXXLiteralIdentifier()); + break; + case DeclarationName::CXXConversionFunctionName: + AddQualType(Name.getCXXNameType()); + break; + case DeclarationName::CXXUsingDirective: + break; + case DeclarationName::CXXDeductionGuideName: { + if (auto *Template = Name.getCXXDeductionGuideTemplate()) + AddDecl(Template); + } + } +} + +void TemplateArgumentHasher::AddDecl(const Decl *D) { + const NamedDecl *ND = dyn_cast(D); + if (!ND) { + BailedOut = true; + return; + } + + AddDeclarationName(ND->getDeclName()); +} + +void TemplateArgumentHasher::AddQualType(QualType T) { + if (T.isNull()) { + BailedOut = true; + return; + } + SplitQualType split = T.split(); + AddInteger(split.Quals.getAsOpaqueValue()); + AddType(split.Ty); +} + +// Process a Type pointer. Add* methods call back into TemplateArgumentHasher +// while Visit* methods process the relevant parts of the Type. +// Any unhandled type will make the hash computation bail out. +class TypeVisitorHelper : public TypeVisitor { + typedef TypeVisitor Inherited; + llvm::FoldingSetNodeID &ID; + TemplateArgumentHasher &Hash; + +public: + TypeVisitorHelper(llvm::FoldingSetNodeID &ID, TemplateArgumentHasher &Hash) + : ID(ID), Hash(Hash) {} + + void AddDecl(const Decl *D) { + if (D) + Hash.AddDecl(D); + else + Hash.AddInteger(0); + } + + void AddQualType(QualType T) { Hash.AddQualType(T); } + + void AddType(const Type *T) { + if (T) + Hash.AddType(T); + else + Hash.AddInteger(0); + } + + void VisitQualifiers(Qualifiers Quals) { + Hash.AddInteger(Quals.getAsOpaqueValue()); + } + + void Visit(const Type *T) { Inherited::Visit(T); } + + // Unhandled types. Bail out simply. + void VisitType(const Type *T) { Hash.setBailedOut(); } + + void VisitAdjustedType(const AdjustedType *T) { + AddQualType(T->getOriginalType()); + } + + void VisitDecayedType(const DecayedType *T) { + // getDecayedType and getPointeeType are derived from getAdjustedType + // and don't need to be separately processed. + VisitAdjustedType(T); + } + + void VisitArrayType(const ArrayType *T) { + AddQualType(T->getElementType()); + Hash.AddInteger(llvm::to_underlying(T->getSizeModifier())); + VisitQualifiers(T->getIndexTypeQualifiers()); + } + void VisitConstantArrayType(const ConstantArrayType *T) { + T->getSize().Profile(ID); + VisitArrayType(T); + } + + void VisitAttributedType(const AttributedType *T) { + Hash.AddInteger(T->getAttrKind()); + AddQualType(T->getModifiedType()); + } + + void VisitBuiltinType(const BuiltinType *T) { Hash.AddInteger(T->getKind()); } + + void VisitComplexType(const ComplexType *T) { + AddQualType(T->getElementType()); + } + + void VisitDecltypeType(const DecltypeType *T) { + AddQualType(T->getUnderlyingType()); + } + + void VisitDeducedType(const DeducedType *T) { + AddQualType(T->getDeducedType()); + } + + void VisitAutoType(const AutoType *T) { VisitDeducedType(T); } + + void VisitDeducedTemplateSpecializationType( + const DeducedTemplateSpecializationType *T) { + Hash.AddTemplateName(T->getTemplateName()); + VisitDeducedType(T); + } + + void VisitFunctionType(const FunctionType *T) { + AddQualType(T->getReturnType()); + T->getExtInfo().Profile(ID); + Hash.AddInteger(T->isConst()); + Hash.AddInteger(T->isVolatile()); + Hash.AddInteger(T->isRestrict()); + } + + void VisitFunctionNoProtoType(const FunctionNoProtoType *T) { + VisitFunctionType(T); + } + + void VisitFunctionProtoType(const FunctionProtoType *T) { + Hash.AddInteger(T->getNumParams()); + for (auto ParamType : T->getParamTypes()) + AddQualType(ParamType); + + VisitFunctionType(T); + } + + void VisitMemberPointerType(const MemberPointerType *T) { + AddQualType(T->getPointeeType()); + AddType(T->getClass()); + } + + void VisitPackExpansionType(const PackExpansionType *T) { + AddQualType(T->getPattern()); + } + + void VisitParenType(const ParenType *T) { AddQualType(T->getInnerType()); } + + void VisitPointerType(const PointerType *T) { + AddQualType(T->getPointeeType()); + } + + void VisitReferenceType(const ReferenceType *T) { + AddQualType(T->getPointeeTypeAsWritten()); + } + + void VisitLValueReferenceType(const LValueReferenceType *T) { + VisitReferenceType(T); + } + + void VisitRValueReferenceType(const RValueReferenceType *T) { + VisitReferenceType(T); + } + + void + VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) { + AddDecl(T->getAssociatedDecl()); + Hash.AddTemplateArgument(T->getArgumentPack()); + } + + void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { + AddDecl(T->getAssociatedDecl()); + AddQualType(T->getReplacementType()); + } + + void VisitTagType(const TagType *T) { AddDecl(T->getDecl()); } + + void VisitRecordType(const RecordType *T) { VisitTagType(T); } + void VisitEnumType(const EnumType *T) { VisitTagType(T); } + + void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { + Hash.AddInteger(T->template_arguments().size()); + for (const auto &TA : T->template_arguments()) { + Hash.AddTemplateArgument(TA); + } + Hash.AddTemplateName(T->getTemplateName()); + } + + void VisitTemplateTypeParmType(const TemplateTypeParmType *T) { + Hash.AddInteger(T->getDepth()); + Hash.AddInteger(T->getIndex()); + Hash.AddInteger(T->isParameterPack()); + } + + void VisitTypedefType(const TypedefType *T) { AddDecl(T->getDecl()); } + + void VisitElaboratedType(const ElaboratedType *T) { + AddQualType(T->getNamedType()); + } + + void VisitUnaryTransformType(const UnaryTransformType *T) { + AddQualType(T->getUnderlyingType()); + AddQualType(T->getBaseType()); + } + + void VisitVectorType(const VectorType *T) { + AddQualType(T->getElementType()); + Hash.AddInteger(T->getNumElements()); + Hash.AddInteger(llvm::to_underlying(T->getVectorKind())); + } + + void VisitExtVectorType(const ExtVectorType *T) { VisitVectorType(T); } +}; + +void TemplateArgumentHasher::AddType(const Type *T) { + assert(T && "Expecting non-null pointer."); + TypeVisitorHelper(ID, *this).Visit(T); +} + +} // namespace + +unsigned clang::serialization::StableHashForTemplateArguments( + llvm::ArrayRef Args) { + TemplateArgumentHasher Hasher; + Hasher.AddInteger(Args.size()); + for (TemplateArgument Arg : Args) + Hasher.AddTemplateArgument(Arg); + return Hasher.getValue(); +} diff --git a/clang/lib/Serialization/TemplateArgumentHasher.h b/clang/lib/Serialization/TemplateArgumentHasher.h new file mode 100644 index 0000000000000..f23f1318afbbf --- /dev/null +++ b/clang/lib/Serialization/TemplateArgumentHasher.h @@ -0,0 +1,34 @@ +//===- TemplateArgumentHasher.h - Hash Template Arguments -------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "clang/AST/TemplateBase.h" + +namespace clang { +namespace serialization { + +/// Calculate a stable hash value for template arguments. We guarantee that +/// the same template arguments must have the same hashed values. But we don't +/// guarantee that the template arguments with the same hashed value are the +/// same template arguments. +/// +/// ODR hashing may not be the best mechanism to hash the template +/// arguments. ODR hashing is (or perhaps, should be) about determining whether +/// two things are spelled the same way and have the same meaning (as required +/// by the C++ ODR), whereas what we want here is whether they have the same +/// meaning regardless of spelling. Maybe we can get away with reusing ODR +/// hashing anyway, on the basis that any canonical, non-dependent template +/// argument should have the same (invented) spelling in every translation +/// unit, but it is not sure that's true in all cases. There may still be cases +/// where the canonical type includes some aspect of "whatever we saw first", +/// in which case the ODR hash can differ across translation units for +/// non-dependent, canonical template arguments that are spelled differently +/// but have the same meaning. But it is not easy to raise examples. +unsigned StableHashForTemplateArguments(llvm::ArrayRef Args); + +} // namespace serialization +} // namespace clang diff --git a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt index 2b15d31053cf4..fcbe8b864b6e4 100644 --- a/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt +++ b/clang/lib/StaticAnalyzer/Checkers/CMakeLists.txt @@ -131,6 +131,7 @@ add_clang_library(clangStaticAnalyzerCheckers VirtualCallChecker.cpp WebKit/RawPtrRefMemberChecker.cpp WebKit/ASTUtils.cpp + WebKit/MemoryUnsafeCastChecker.cpp WebKit/PtrTypesSemantics.cpp WebKit/RefCntblBaseVirtualDtorChecker.cpp WebKit/RawPtrRefCallArgsChecker.cpp diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp index b3cd594a0f352..abf5d3ec193a4 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.cpp @@ -13,6 +13,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/StmtVisitor.h" #include namespace clang { @@ -33,7 +34,7 @@ bool tryToFindPtrOrigin( E = tempExpr->getSubExpr(); continue; } - if (auto *tempExpr = dyn_cast(E)) { + if (auto *tempExpr = dyn_cast(E)) { if (auto *C = tempExpr->getConstructor()) { if (auto *Class = C->getParent(); Class && isSafePtr(Class)) return callback(E, true); @@ -158,6 +159,9 @@ bool isConstOwnerPtrMemberExpr(const clang::Expr *E) { E = ThisArg; } } + } else if (auto *OCE = dyn_cast(E)) { + if (OCE->getOperator() == OO_Star && OCE->getNumArgs() == 1) + E = OCE->getArg(0); } auto *ME = dyn_cast(E); if (!ME) @@ -169,4 +173,42 @@ bool isConstOwnerPtrMemberExpr(const clang::Expr *E) { return isOwnerPtrType(T) && T.isConstQualified(); } +class EnsureFunctionVisitor + : public ConstStmtVisitor { +public: + bool VisitStmt(const Stmt *S) { + for (const Stmt *Child : S->children()) { + if (Child && !Visit(Child)) + return false; + } + return true; + } + + bool VisitReturnStmt(const ReturnStmt *RS) { + if (auto *RV = RS->getRetValue()) { + RV = RV->IgnoreParenCasts(); + if (isa(RV)) + return true; + return isConstOwnerPtrMemberExpr(RV); + } + return false; + } +}; + +bool EnsureFunctionAnalysis::isACallToEnsureFn(const clang::Expr *E) const { + auto *MCE = dyn_cast(E); + if (!MCE) + return false; + auto *Callee = MCE->getDirectCallee(); + if (!Callee) + return false; + auto *Body = Callee->getBody(); + if (!Body) + return false; + auto [CacheIt, IsNew] = Cache.insert(std::make_pair(Callee, false)); + if (IsNew) + CacheIt->second = EnsureFunctionVisitor().Visit(Body); + return CacheIt->second; +} + } // namespace clang diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h index ddbef0fba0448..b508043d0f37f 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/ASTUtils.h @@ -67,6 +67,16 @@ bool isASafeCallArg(const clang::Expr *E); /// \returns true if E is a MemberExpr accessing a const smart pointer type. bool isConstOwnerPtrMemberExpr(const clang::Expr *E); +/// \returns true if E is a CXXMemberCallExpr which returns a const smart +/// pointer type. +class EnsureFunctionAnalysis { + using CacheTy = llvm::DenseMap; + mutable CacheTy Cache{}; + +public: + bool isACallToEnsureFn(const Expr *E) const; +}; + /// \returns name of AST node or empty string. template std::string safeGetName(const T *ASTNode) { const auto *const ND = llvm::dyn_cast_or_null(ASTNode); diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/MemoryUnsafeCastChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/MemoryUnsafeCastChecker.cpp new file mode 100644 index 0000000000000..eeaccf9b70524 --- /dev/null +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/MemoryUnsafeCastChecker.cpp @@ -0,0 +1,188 @@ +//=======- MemoryUnsafeCastChecker.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 +// +//===----------------------------------------------------------------------===// +// +// This file defines MemoryUnsafeCast checker, which checks for casts from a +// base type to a derived type. +//===----------------------------------------------------------------------===// + +#include "clang/ASTMatchers/ASTMatchFinder.h" +#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" +#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h" +#include "clang/StaticAnalyzer/Core/Checker.h" +#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" + +using namespace clang; +using namespace ento; +using namespace ast_matchers; + +namespace { +static constexpr const char *const BaseNode = "BaseNode"; +static constexpr const char *const DerivedNode = "DerivedNode"; +static constexpr const char *const FromCastNode = "FromCast"; +static constexpr const char *const ToCastNode = "ToCast"; +static constexpr const char *const WarnRecordDecl = "WarnRecordDecl"; + +class MemoryUnsafeCastChecker : public Checker { + BugType BT{this, "Unsafe cast", "WebKit coding guidelines"}; + +public: + void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr, + BugReporter &BR) const; +}; +} // end namespace + +static void emitDiagnostics(const BoundNodes &Nodes, BugReporter &BR, + AnalysisDeclContext *ADC, + const MemoryUnsafeCastChecker *Checker, + const BugType &BT) { + const auto *CE = Nodes.getNodeAs(WarnRecordDecl); + const NamedDecl *Base = Nodes.getNodeAs(BaseNode); + const NamedDecl *Derived = Nodes.getNodeAs(DerivedNode); + assert(CE && Base && Derived); + + std::string Diagnostics; + llvm::raw_string_ostream OS(Diagnostics); + OS << "Unsafe cast from base type '" << Base->getNameAsString() + << "' to derived type '" << Derived->getNameAsString() << "'"; + PathDiagnosticLocation BSLoc(CE->getSourceRange().getBegin(), + BR.getSourceManager()); + auto Report = std::make_unique(BT, OS.str(), BSLoc); + Report->addRange(CE->getSourceRange()); + BR.emitReport(std::move(Report)); +} + +static void emitDiagnosticsUnrelated(const BoundNodes &Nodes, BugReporter &BR, + AnalysisDeclContext *ADC, + const MemoryUnsafeCastChecker *Checker, + const BugType &BT) { + const auto *CE = Nodes.getNodeAs(WarnRecordDecl); + const NamedDecl *FromCast = Nodes.getNodeAs(FromCastNode); + const NamedDecl *ToCast = Nodes.getNodeAs(ToCastNode); + assert(CE && FromCast && ToCast); + + std::string Diagnostics; + llvm::raw_string_ostream OS(Diagnostics); + OS << "Unsafe cast from type '" << FromCast->getNameAsString() + << "' to an unrelated type '" << ToCast->getNameAsString() << "'"; + PathDiagnosticLocation BSLoc(CE->getSourceRange().getBegin(), + BR.getSourceManager()); + auto Report = std::make_unique(BT, OS.str(), BSLoc); + Report->addRange(CE->getSourceRange()); + BR.emitReport(std::move(Report)); +} + +namespace clang { +namespace ast_matchers { +AST_MATCHER_P(StringLiteral, mentionsBoundType, std::string, BindingID) { + return Builder->removeBindings([this, &Node](const BoundNodesMap &Nodes) { + const auto &BN = Nodes.getNode(this->BindingID); + if (const auto *ND = BN.get()) { + return ND->getName() != Node.getString(); + } + return true; + }); +} +} // end namespace ast_matchers +} // end namespace clang + +static decltype(auto) hasTypePointingTo(DeclarationMatcher DeclM) { + return hasType(pointerType(pointee(hasDeclaration(DeclM)))); +} + +void MemoryUnsafeCastChecker::checkASTCodeBody(const Decl *D, + AnalysisManager &AM, + BugReporter &BR) const { + + AnalysisDeclContext *ADC = AM.getAnalysisDeclContext(D); + + // Match downcasts from base type to derived type and warn + auto MatchExprPtr = allOf( + hasSourceExpression(hasTypePointingTo(cxxRecordDecl().bind(BaseNode))), + hasTypePointingTo(cxxRecordDecl(isDerivedFrom(equalsBoundNode(BaseNode))) + .bind(DerivedNode)), + unless(anyOf(hasSourceExpression(cxxThisExpr()), + hasTypePointingTo(templateTypeParmDecl())))); + auto MatchExprPtrObjC = allOf( + hasSourceExpression(ignoringImpCasts(hasType(objcObjectPointerType( + pointee(hasDeclaration(objcInterfaceDecl().bind(BaseNode))))))), + ignoringImpCasts(hasType(objcObjectPointerType(pointee(hasDeclaration( + objcInterfaceDecl(isDerivedFrom(equalsBoundNode(BaseNode))) + .bind(DerivedNode))))))); + auto MatchExprRefTypeDef = + allOf(hasSourceExpression(hasType(hasUnqualifiedDesugaredType(recordType( + hasDeclaration(decl(cxxRecordDecl().bind(BaseNode))))))), + hasType(hasUnqualifiedDesugaredType(recordType(hasDeclaration( + decl(cxxRecordDecl(isDerivedFrom(equalsBoundNode(BaseNode))) + .bind(DerivedNode)))))), + unless(anyOf(hasSourceExpression(hasDescendant(cxxThisExpr())), + hasType(templateTypeParmDecl())))); + + auto ExplicitCast = explicitCastExpr(anyOf(MatchExprPtr, MatchExprRefTypeDef, + MatchExprPtrObjC)) + .bind(WarnRecordDecl); + auto Cast = stmt(ExplicitCast); + + auto Matches = + match(stmt(forEachDescendant(Cast)), *D->getBody(), AM.getASTContext()); + for (BoundNodes Match : Matches) + emitDiagnostics(Match, BR, ADC, this, BT); + + // Match casts between unrelated types and warn + auto MatchExprPtrUnrelatedTypes = allOf( + hasSourceExpression( + hasTypePointingTo(cxxRecordDecl().bind(FromCastNode))), + hasTypePointingTo(cxxRecordDecl().bind(ToCastNode)), + unless(anyOf(hasTypePointingTo(cxxRecordDecl( + isSameOrDerivedFrom(equalsBoundNode(FromCastNode)))), + hasSourceExpression(hasTypePointingTo(cxxRecordDecl( + isSameOrDerivedFrom(equalsBoundNode(ToCastNode)))))))); + auto MatchExprPtrObjCUnrelatedTypes = allOf( + hasSourceExpression(ignoringImpCasts(hasType(objcObjectPointerType( + pointee(hasDeclaration(objcInterfaceDecl().bind(FromCastNode))))))), + ignoringImpCasts(hasType(objcObjectPointerType( + pointee(hasDeclaration(objcInterfaceDecl().bind(ToCastNode)))))), + unless(anyOf( + ignoringImpCasts(hasType( + objcObjectPointerType(pointee(hasDeclaration(objcInterfaceDecl( + isSameOrDerivedFrom(equalsBoundNode(FromCastNode)))))))), + hasSourceExpression(ignoringImpCasts(hasType( + objcObjectPointerType(pointee(hasDeclaration(objcInterfaceDecl( + isSameOrDerivedFrom(equalsBoundNode(ToCastNode)))))))))))); + auto MatchExprRefTypeDefUnrelated = allOf( + hasSourceExpression(hasType(hasUnqualifiedDesugaredType(recordType( + hasDeclaration(decl(cxxRecordDecl().bind(FromCastNode))))))), + hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl(cxxRecordDecl().bind(ToCastNode)))))), + unless(anyOf( + hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl(cxxRecordDecl( + isSameOrDerivedFrom(equalsBoundNode(FromCastNode)))))))), + hasSourceExpression(hasType(hasUnqualifiedDesugaredType( + recordType(hasDeclaration(decl(cxxRecordDecl( + isSameOrDerivedFrom(equalsBoundNode(ToCastNode)))))))))))); + + auto ExplicitCastUnrelated = + explicitCastExpr(anyOf(MatchExprPtrUnrelatedTypes, + MatchExprPtrObjCUnrelatedTypes, + MatchExprRefTypeDefUnrelated)) + .bind(WarnRecordDecl); + auto CastUnrelated = stmt(ExplicitCastUnrelated); + auto MatchesUnrelatedTypes = match(stmt(forEachDescendant(CastUnrelated)), + *D->getBody(), AM.getASTContext()); + for (BoundNodes Match : MatchesUnrelatedTypes) + emitDiagnosticsUnrelated(Match, BR, ADC, this, BT); +} + +void ento::registerMemoryUnsafeCastChecker(CheckerManager &Mgr) { + Mgr.registerChecker(); +} + +bool ento::shouldRegisterMemoryUnsafeCastChecker(const CheckerManager &mgr) { + return true; +} diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp index ef2d42ccada65..56fa72c100ec8 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefCallArgsChecker.cpp @@ -33,6 +33,7 @@ class RawPtrRefCallArgsChecker mutable BugReporter *BR; TrivialFunctionAnalysis TFA; + EnsureFunctionAnalysis EFA; public: RawPtrRefCallArgsChecker(const char *description) @@ -140,7 +141,7 @@ class RawPtrRefCallArgsChecker bool isPtrOriginSafe(const Expr *Arg) const { return tryToFindPtrOrigin(Arg, /*StopAtFirstRefCountedObj=*/true, - [](const clang::Expr *ArgOrigin, bool IsSafe) { + [&](const clang::Expr *ArgOrigin, bool IsSafe) { if (IsSafe) return true; if (isa(ArgOrigin)) { @@ -154,6 +155,8 @@ class RawPtrRefCallArgsChecker } if (isASafeCallArg(ArgOrigin)) return true; + if (EFA.isACallToEnsureFn(ArgOrigin)) + return true; return false; }); } diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp index e0433c5c2c1a0..d586668399502 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RawPtrRefLocalVarsChecker.cpp @@ -166,6 +166,7 @@ class RawPtrRefLocalVarsChecker : public Checker> { BugType Bug; mutable BugReporter *BR; + EnsureFunctionAnalysis EFA; public: RawPtrRefLocalVarsChecker(const char *description) @@ -263,7 +264,7 @@ class RawPtrRefLocalVarsChecker if (tryToFindPtrOrigin( Value, /*StopAtFirstRefCountedObj=*/false, [&](const clang::Expr *InitArgOrigin, bool IsSafe) { - if (!InitArgOrigin) + if (!InitArgOrigin || IsSafe) return true; if (isa(InitArgOrigin)) @@ -278,6 +279,9 @@ class RawPtrRefLocalVarsChecker if (isConstOwnerPtrMemberExpr(InitArgOrigin)) return true; + if (EFA.isACallToEnsureFn(InitArgOrigin)) + return true; + if (auto *Ref = llvm::dyn_cast(InitArgOrigin)) { if (auto *MaybeGuardian = dyn_cast_or_null(Ref->getFoundDecl())) { diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp index 599c2179db0f0..ac5cf3d899d55 100644 --- a/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/UncountedLambdaCapturesChecker.cpp @@ -40,6 +40,7 @@ class UncountedLambdaCapturesChecker struct LocalVisitor : DynamicRecursiveASTVisitor { const UncountedLambdaCapturesChecker *Checker; llvm::DenseSet DeclRefExprsToIgnore; + llvm::DenseSet LambdasToIgnore; QualType ClsType; explicit LocalVisitor(const UncountedLambdaCapturesChecker *Checker) @@ -61,6 +62,24 @@ class UncountedLambdaCapturesChecker return result && *result; } + bool VisitLambdaExpr(LambdaExpr *L) override { + if (LambdasToIgnore.contains(L)) + return true; + Checker->visitLambdaExpr(L, shouldCheckThis()); + return true; + } + + bool VisitVarDecl(VarDecl *VD) override { + auto *Init = VD->getInit(); + if (!Init) + return true; + auto *L = dyn_cast_or_null(Init->IgnoreParenCasts()); + if (!L) + return true; + LambdasToIgnore.insert(L); // Evaluate lambdas in VisitDeclRefExpr. + return true; + } + bool VisitDeclRefExpr(DeclRefExpr *DRE) override { if (DeclRefExprsToIgnore.contains(DRE)) return true; @@ -73,6 +92,7 @@ class UncountedLambdaCapturesChecker auto *L = dyn_cast_or_null(Init->IgnoreParenCasts()); if (!L) return true; + LambdasToIgnore.insert(L); Checker->visitLambdaExpr(L, shouldCheckThis()); return true; } @@ -95,10 +115,10 @@ class UncountedLambdaCapturesChecker if (ArgIndex >= CE->getNumArgs()) return true; auto *Arg = CE->getArg(ArgIndex)->IgnoreParenCasts(); - if (!Param->hasAttr() && !TreatAllArgsAsNoEscape) { - if (auto *L = dyn_cast_or_null(Arg)) { + if (auto *L = dyn_cast_or_null(Arg)) { + LambdasToIgnore.insert(L); + if (!Param->hasAttr() && !TreatAllArgsAsNoEscape) Checker->visitLambdaExpr(L, shouldCheckThis()); - } } ++ArgIndex; } @@ -117,6 +137,10 @@ class UncountedLambdaCapturesChecker if (!MD || CE->getNumArgs() < 1) return; auto *Arg = CE->getArg(0)->IgnoreParenCasts(); + if (auto *L = dyn_cast_or_null(Arg)) { + LambdasToIgnore.insert(L); // Calling a lambda upon creation is safe. + return; + } auto *ArgRef = dyn_cast(Arg); if (!ArgRef) return; @@ -130,6 +154,7 @@ class UncountedLambdaCapturesChecker if (!L) return; DeclRefExprsToIgnore.insert(ArgRef); + LambdasToIgnore.insert(L); Checker->visitLambdaExpr(L, shouldCheckThis(), /* ignoreParamVarDecl */ true); } diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index b46cd9fe86fc1..ae43c59511bfa 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1825,6 +1825,10 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred, case Stmt::OpenACCComputeConstructClass: case Stmt::OpenACCLoopConstructClass: case Stmt::OpenACCCombinedConstructClass: + case Stmt::OpenACCDataConstructClass: + case Stmt::OpenACCEnterDataConstructClass: + case Stmt::OpenACCExitDataConstructClass: + case Stmt::OpenACCHostDataConstructClass: case Stmt::OMPUnrollDirectiveClass: case Stmt::OMPMetaDirectiveClass: case Stmt::HLSLOutArgExprClass: { diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc index 8f20ce98152f0..9179217dd6ca8 100644 --- a/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc +++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSpecialSymbolMap.inc @@ -261,6 +261,11 @@ SYMBOL(data, std::ranges::, ) SYMBOL(data, std::ranges::, ) SYMBOL(cdata, std::ranges::, ) SYMBOL(cdata, std::ranges::, ) +// https://eel.is/c++draft/tuple.general#2: +// In addition to being available via inclusion of the header, +// ignore ... is available when ... is included. +SYMBOL(ignore, std::, ) +SYMBOL(ignore, std::, ) // Ignore specializations SYMBOL(hash, std::, ) @@ -389,18 +394,10 @@ SYMBOL(make_error_condition, std::, /*no headers*/) SYMBOL(erase, std::, /*no headers*/) SYMBOL(erase_if, std::, /*no headers*/) -// cppreference symbol index page was missing these symbols. -// Remove them when the cppreference offline archive catches up. -SYMBOL(regular_invocable, std::, ) - // Symbols missing from the generated symbol map as reported by users. // Remove when the generator starts producing them. SYMBOL(div, std::, ) SYMBOL(abort, std::, ) -SYMBOL(atomic_wait, std::, ) -SYMBOL(atomic_wait_explicit, std::, ) -SYMBOL(move_backward, std::, ) -SYMBOL(month_weekday, std::chrono::, ) SYMBOL(binary_search, std::ranges::, ) SYMBOL(equal_range, std::ranges::, ) diff --git a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc index b4afd0228694f..c1927180d3397 100644 --- a/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc +++ b/clang/lib/Tooling/Inclusions/Stdlib/StdSymbolMap.inc @@ -6,7 +6,7 @@ // This file was generated automatically by // clang/tools/include-mapping/gen_std.py, DO NOT EDIT! // -// Generated from cppreference offline HTML book (modified on 2024-06-10). +// Generated from cppreference offline HTML book (modified on 2024-11-10). //===----------------------------------------------------------------------===// SYMBOL(ATOMIC_BOOL_LOCK_FREE, None, ) @@ -578,6 +578,7 @@ SYMBOL(add_pointer, std::, ) SYMBOL(add_pointer_t, std::, ) SYMBOL(add_rvalue_reference, std::, ) SYMBOL(add_rvalue_reference_t, std::, ) +SYMBOL(add_sat, std::, ) SYMBOL(add_volatile, std::, ) SYMBOL(add_volatile_t, std::, ) SYMBOL(addressof, std::, ) @@ -699,6 +700,10 @@ SYMBOL(atomic_fetch_add, std::, ) SYMBOL(atomic_fetch_add_explicit, std::, ) SYMBOL(atomic_fetch_and, std::, ) SYMBOL(atomic_fetch_and_explicit, std::, ) +SYMBOL(atomic_fetch_max, std::, ) +SYMBOL(atomic_fetch_max_explicit, std::, ) +SYMBOL(atomic_fetch_min, std::, ) +SYMBOL(atomic_fetch_min_explicit, std::, ) SYMBOL(atomic_fetch_or, std::, ) SYMBOL(atomic_fetch_or_explicit, std::, ) SYMBOL(atomic_fetch_sub, std::, ) @@ -727,6 +732,8 @@ SYMBOL(atomic_signal_fence, std::, ) SYMBOL(atomic_store, std::, ) SYMBOL(atomic_store_explicit, std::, ) SYMBOL(atomic_thread_fence, std::, ) +SYMBOL(atomic_wait, std::, ) +SYMBOL(atomic_wait_explicit, std::, ) SYMBOL(atto, std::, ) SYMBOL(auto_ptr, std::, ) SYMBOL(back_insert_iterator, std::, ) @@ -829,6 +836,8 @@ SYMBOL(boolalpha, std::, ) SYMBOL(boolalpha, std::, ) SYMBOL(boyer_moore_horspool_searcher, std::, ) SYMBOL(boyer_moore_searcher, std::, ) +SYMBOL(breakpoint, std::, ) +SYMBOL(breakpoint_if_debugging, std::, ) SYMBOL(bsearch, std::, ) SYMBOL(bsearch, None, ) SYMBOL(bsearch, None, ) @@ -951,6 +960,7 @@ SYMBOL(copy_constructible, std::, ) SYMBOL(copy_if, std::, ) SYMBOL(copy_n, std::, ) SYMBOL(copyable, std::, ) +SYMBOL(copyable_function, std::, ) SYMBOL(copysign, std::, ) SYMBOL(copysign, None, ) SYMBOL(copysign, None, ) @@ -1048,12 +1058,14 @@ SYMBOL(dextents, std::, ) SYMBOL(difftime, std::, ) SYMBOL(difftime, None, ) SYMBOL(difftime, None, ) +SYMBOL(dims, std::, ) SYMBOL(disable_sized_sentinel_for, std::, ) SYMBOL(discard_block_engine, std::, ) SYMBOL(discrete_distribution, std::, ) SYMBOL(disjunction, std::, ) SYMBOL(disjunction_v, std::, ) SYMBOL(distance, std::, ) +SYMBOL(div_sat, std::, ) SYMBOL(div_t, std::, ) SYMBOL(div_t, None, ) SYMBOL(div_t, None, ) @@ -1077,6 +1089,7 @@ SYMBOL(emit_on_flush, std::, ) SYMBOL(emit_on_flush, std::, ) SYMBOL(enable_if, std::, ) SYMBOL(enable_if_t, std::, ) +SYMBOL(enable_nonlocking_formatter_optimization, std::, ) SYMBOL(enable_shared_from_this, std::, ) SYMBOL(endian, std::, ) SYMBOL(endl, std::, ) @@ -1241,8 +1254,7 @@ SYMBOL(fgetwc, None, ) SYMBOL(fgetws, std::, ) SYMBOL(fgetws, None, ) SYMBOL(fgetws, None, ) -SYMBOL(filebuf, std::, ) -SYMBOL(filebuf, std::, ) +SYMBOL(filebuf, std::, ) SYMBOL(filebuf, std::, ) SYMBOL(fill, std::, ) SYMBOL(fill_n, std::, ) @@ -1322,11 +1334,13 @@ SYMBOL(format, std::, ) SYMBOL(format_args, std::, ) SYMBOL(format_context, std::, ) SYMBOL(format_error, std::, ) +SYMBOL(format_kind, std::, ) SYMBOL(format_parse_context, std::, ) SYMBOL(format_string, std::, ) SYMBOL(format_to, std::, ) SYMBOL(format_to_n, std::, ) SYMBOL(format_to_n_result, std::, ) +SYMBOL(formattable, std::, ) SYMBOL(formatted_size, std::, ) SYMBOL(formatter, std::, ) SYMBOL(forward, std::, ) @@ -1398,6 +1412,7 @@ SYMBOL(ftell, std::, ) SYMBOL(ftell, None, ) SYMBOL(ftell, None, ) SYMBOL(function, std::, ) +SYMBOL(function_ref, std::, ) SYMBOL(future, std::, ) SYMBOL(future_category, std::, ) SYMBOL(future_errc, std::, ) @@ -1488,7 +1503,6 @@ SYMBOL(hypotl, None, ) SYMBOL(identity, std::, ) SYMBOL(ifstream, std::, ) SYMBOL(ifstream, std::, ) -SYMBOL(ignore, std::, ) SYMBOL(ilogb, std::, ) SYMBOL(ilogb, None, ) SYMBOL(ilogb, None, ) @@ -1544,6 +1558,7 @@ SYMBOL(inner_product, std::, ) SYMBOL(inout_ptr, std::, ) SYMBOL(inout_ptr_t, std::, ) SYMBOL(inplace_merge, std::, ) +SYMBOL(inplace_vector, std::, ) SYMBOL(input_iterator, std::, ) SYMBOL(input_iterator_tag, std::, ) SYMBOL(input_or_output_iterator, std::, ) @@ -1649,6 +1664,7 @@ SYMBOL(is_copy_assignable_v, std::, ) SYMBOL(is_copy_constructible, std::, ) SYMBOL(is_copy_constructible_v, std::, ) SYMBOL(is_corresponding_member, std::, ) +SYMBOL(is_debugger_present, std::, ) SYMBOL(is_default_constructible, std::, ) SYMBOL(is_default_constructible_v, std::, ) SYMBOL(is_destructible, std::, ) @@ -1790,6 +1806,8 @@ SYMBOL(is_union, std::, ) SYMBOL(is_union_v, std::, ) SYMBOL(is_unsigned, std::, ) SYMBOL(is_unsigned_v, std::, ) +SYMBOL(is_virtual_base_of, std::, ) +SYMBOL(is_virtual_base_of_v, std::, ) SYMBOL(is_void, std::, ) SYMBOL(is_void_v, std::, ) SYMBOL(is_volatile, std::, ) @@ -1938,7 +1956,9 @@ SYMBOL(latch, std::, ) SYMBOL(launch, std::, ) SYMBOL(launder, std::, ) SYMBOL(layout_left, std::, ) +SYMBOL(layout_left_padded, std::, ) SYMBOL(layout_right, std::, ) +SYMBOL(layout_right_padded, std::, ) SYMBOL(layout_stride, std::, ) SYMBOL(lcm, std::, ) SYMBOL(lconv, std::, ) @@ -2222,6 +2242,7 @@ SYMBOL(moneypunct, std::, ) SYMBOL(moneypunct_byname, std::, ) SYMBOL(monostate, std::, ) SYMBOL(movable, std::, ) +SYMBOL(move_backward, std::, ) SYMBOL(move_constructible, std::, ) SYMBOL(move_if_noexcept, std::, ) SYMBOL(move_iterator, std::, ) @@ -2229,6 +2250,7 @@ SYMBOL(move_only_function, std::, ) SYMBOL(move_sentinel, std::, ) SYMBOL(mt19937, std::, ) SYMBOL(mt19937_64, std::, ) +SYMBOL(mul_sat, std::, ) SYMBOL(multimap, std::, ) SYMBOL(multiplies, std::, ) SYMBOL(multiset, std::, ) @@ -2283,6 +2305,8 @@ SYMBOL(noboolalpha, std::, ) SYMBOL(noemit_on_flush, std::, ) SYMBOL(noemit_on_flush, std::, ) SYMBOL(none_of, std::, ) +SYMBOL(nontype, std::, ) +SYMBOL(nontype_t, std::, ) SYMBOL(noop_coroutine, std::, ) SYMBOL(noop_coroutine_handle, std::, ) SYMBOL(noop_coroutine_promise, std::, ) @@ -2442,6 +2466,8 @@ SYMBOL(random_access_iterator_tag, std::, ) SYMBOL(random_device, std::, ) SYMBOL(random_shuffle, std::, ) SYMBOL(range_error, std::, ) +SYMBOL(range_format, std::, ) +SYMBOL(range_formatter, std::, ) SYMBOL(rank, std::, ) SYMBOL(rank_v, std::, ) SYMBOL(ranlux24, std::, ) @@ -2486,6 +2512,7 @@ SYMBOL(regex_search, std::, ) SYMBOL(regex_token_iterator, std::, ) SYMBOL(regex_traits, std::, ) SYMBOL(regular, std::, ) +SYMBOL(regular_invocable, std::, ) SYMBOL(reinterpret_pointer_cast, std::, ) SYMBOL(relation, std::, ) SYMBOL(relaxed, std::, ) @@ -2580,8 +2607,10 @@ SYMBOL(roundl, std::, ) SYMBOL(roundl, None, ) SYMBOL(roundl, None, ) SYMBOL(runtime_error, std::, ) +SYMBOL(runtime_format, std::, ) SYMBOL(same_as, std::, ) SYMBOL(sample, std::, ) +SYMBOL(saturate_cast, std::, ) SYMBOL(scalbln, std::, ) SYMBOL(scalbln, None, ) SYMBOL(scalbln, None, ) @@ -2786,6 +2815,7 @@ SYMBOL(strftime, None, ) SYMBOL(strftime, None, ) SYMBOL(strict, std::, ) SYMBOL(strict_weak_order, std::, ) +SYMBOL(strided_slice, std::, ) SYMBOL(string, std::, ) SYMBOL(string_view, std::, ) SYMBOL(stringbuf, std::, ) @@ -2857,6 +2887,8 @@ SYMBOL(strxfrm, None, ) SYMBOL(strxfrm, None, ) SYMBOL(student_t_distribution, std::, ) SYMBOL(sub_match, std::, ) +SYMBOL(sub_sat, std::, ) +SYMBOL(submdspan_mapping_result, std::, ) SYMBOL(subtract_with_carry_engine, std::, ) SYMBOL(suspend_always, std::, ) SYMBOL(suspend_never, std::, ) @@ -2897,6 +2929,7 @@ SYMBOL(tanl, None, ) SYMBOL(tera, std::, ) SYMBOL(terminate, std::, ) SYMBOL(terminate_handler, std::, ) +SYMBOL(text_encoding, std::, ) SYMBOL(tgamma, std::, ) SYMBOL(tgamma, None, ) SYMBOL(tgamma, None, ) @@ -3127,7 +3160,9 @@ SYMBOL(visit, std::, ) SYMBOL(visit_format_arg, std::, ) SYMBOL(void_t, std::, ) SYMBOL(vprint_nonunicode, std::, ) +SYMBOL(vprint_nonunicode_buffered, std::, ) SYMBOL(vprint_unicode, std::, ) +SYMBOL(vprint_unicode_buffered, std::, ) SYMBOL(vprintf, std::, ) SYMBOL(vprintf, None, ) SYMBOL(vprintf, None, ) @@ -3156,6 +3191,7 @@ SYMBOL(vwscanf, std::, ) SYMBOL(vwscanf, None, ) SYMBOL(vwscanf, None, ) SYMBOL(wbuffer_convert, std::, ) +SYMBOL(wbuffer_convert, std::, ) SYMBOL(wcerr, std::, ) SYMBOL(wcin, std::, ) SYMBOL(wclog, std::, ) @@ -3274,8 +3310,7 @@ SYMBOL(weak_ordering, std::, ) SYMBOL(weak_ptr, std::, ) SYMBOL(weakly_incrementable, std::, ) SYMBOL(weibull_distribution, std::, ) -SYMBOL(wfilebuf, std::, ) -SYMBOL(wfilebuf, std::, ) +SYMBOL(wfilebuf, std::, ) SYMBOL(wfilebuf, std::, ) SYMBOL(wformat_args, std::, ) SYMBOL(wformat_context, std::, ) @@ -3348,6 +3383,7 @@ SYMBOL(wstreampos, std::, ) SYMBOL(wstreampos, std::, ) SYMBOL(wstring, std::, ) SYMBOL(wstring_convert, std::, ) +SYMBOL(wstring_convert, std::, ) SYMBOL(wstring_view, std::, ) SYMBOL(wstringbuf, std::, ) SYMBOL(wstringbuf, std::, ) @@ -3423,6 +3459,7 @@ SYMBOL(minutes, std::chrono::, ) SYMBOL(month, std::chrono::, ) SYMBOL(month_day, std::chrono::, ) SYMBOL(month_day_last, std::chrono::, ) +SYMBOL(month_weekday, std::chrono::, ) SYMBOL(month_weekday_last, std::chrono::, ) SYMBOL(nanoseconds, std::chrono::, ) SYMBOL(nonexistent_local_time, std::chrono::, ) @@ -3605,6 +3642,7 @@ SYMBOL(chunk_view, std::ranges::, ) SYMBOL(clamp, std::ranges::, ) SYMBOL(common_range, std::ranges::, ) SYMBOL(common_view, std::ranges::, ) +SYMBOL(concat_view, std::ranges::, ) SYMBOL(const_iterator_t, std::ranges::, ) SYMBOL(constant_range, std::ranges::, ) SYMBOL(construct_at, std::ranges::, ) @@ -3629,11 +3667,13 @@ SYMBOL(disable_sized_range, std::ranges::, ) SYMBOL(distance, std::ranges::, ) SYMBOL(drop_view, std::ranges::, ) SYMBOL(drop_while_view, std::ranges::, ) +SYMBOL(elements_of, std::ranges::, ) SYMBOL(elements_view, std::ranges::, ) SYMBOL(empty_view, std::ranges::, ) SYMBOL(enable_borrowed_range, std::ranges::, ) SYMBOL(enable_view, std::ranges::, ) SYMBOL(ends_with, std::ranges::, ) +SYMBOL(enumerate_view, std::ranges::, ) SYMBOL(equal, std::ranges::, ) SYMBOL(equal_to, std::ranges::, ) SYMBOL(fill, std::ranges::, ) @@ -3833,11 +3873,13 @@ SYMBOL(cartesian_product, std::ranges::views::, ) SYMBOL(chunk, std::ranges::views::, ) SYMBOL(chunk_by, std::ranges::views::, ) SYMBOL(common, std::ranges::views::, ) +SYMBOL(concat, std::ranges::views::, ) SYMBOL(counted, std::ranges::views::, ) SYMBOL(drop, std::ranges::views::, ) SYMBOL(drop_while, std::ranges::views::, ) SYMBOL(elements, std::ranges::views::, ) SYMBOL(empty, std::ranges::views::, ) +SYMBOL(enumerate, std::ranges::views::, ) SYMBOL(filter, std::ranges::views::, ) SYMBOL(iota, std::ranges::views::, ) SYMBOL(istream, std::ranges::views::, ) @@ -3914,11 +3956,13 @@ SYMBOL(cartesian_product, std::views::, ) SYMBOL(chunk, std::views::, ) SYMBOL(chunk_by, std::views::, ) SYMBOL(common, std::views::, ) +SYMBOL(concat, std::views::, ) SYMBOL(counted, std::views::, ) SYMBOL(drop, std::views::, ) SYMBOL(drop_while, std::views::, ) SYMBOL(elements, std::views::, ) SYMBOL(empty, std::views::, ) +SYMBOL(enumerate, std::views::, ) SYMBOL(filter, std::views::, ) SYMBOL(iota, std::views::, ) SYMBOL(istream, std::views::, ) diff --git a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes index c5171e2f287d2..88e0da1382d6c 100644 --- a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes +++ b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes @@ -3,6 +3,12 @@ Name: SwiftImportAs Tags: - Name: ImmortalRefType SwiftImportAs: reference + Methods: + - Name: methodReturningFrt__ + - Name: methodReturningFrt_returns_unretained + SwiftReturnOwnership: unretained + - Name: methodReturningFrt_returns_retained + SwiftReturnOwnership: retained - Name: RefCountedType SwiftImportAs: reference SwiftReleaseOp: RCRelease @@ -17,3 +23,10 @@ Tags: SwiftEscapable: false - Name: EscapableType SwiftEscapable: true + +Functions: + - Name: functionReturningFrt__ + - Name: functionReturningFrt_returns_unretained + SwiftReturnOwnership: unretained + - Name: functionReturningFrt_returns_retained + SwiftReturnOwnership: retained diff --git a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h index f205cd3c6e7b7..b6900fee8a979 100644 --- a/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h +++ b/clang/test/APINotes/Inputs/Headers/SwiftImportAs.h @@ -1,4 +1,13 @@ -struct ImmortalRefType {}; +struct ImmortalRefType { + ImmortalRefType * methodReturningFrt__(void); + ImmortalRefType * methodReturningFrt_returns_unretained(void); + ImmortalRefType * methodReturningFrt_returns_retained(void); +}; + +ImmortalRefType * functionReturningFrt__(void); +ImmortalRefType * functionReturningFrt_returns_unretained(void); +ImmortalRefType * functionReturningFrt_returns_retained(void); + struct RefCountedType { int value; }; diff --git a/clang/test/APINotes/swift-import-as.cpp b/clang/test/APINotes/swift-import-as.cpp index d0e7e31fc1d72..3981ef1ed419a 100644 --- a/clang/test/APINotes/swift-import-as.cpp +++ b/clang/test/APINotes/swift-import-as.cpp @@ -6,6 +6,12 @@ // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter CopyableType | FileCheck -check-prefix=CHECK-COPYABLE %s // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter NonEscapableType | FileCheck -check-prefix=CHECK-NON-ESCAPABLE %s // RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter EscapableType | FileCheck -check-prefix=CHECK-ESCAPABLE %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter functionReturningFrt__ | FileCheck -check-prefix=CHECK-FUNCTION-RETURNING-FRT %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter functionReturningFrt_returns_unretained | FileCheck -check-prefix=CHECK-FUNCTION-RETURNING-FRT-UNRETAINED %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter functionReturningFrt_returns_retained | FileCheck -check-prefix=CHECK-FUNCTION-RETURNING-FRT-RETAINED %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter methodReturningFrt__ | FileCheck -check-prefix=CHECK-METHOD-RETURNING-FRT %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter methodReturningFrt_returns_unretained | FileCheck -check-prefix=CHECK-METHOD-RETURNING-FRT-UNRETAINED %s +// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter methodReturningFrt_returns_retained | FileCheck -check-prefix=CHECK-METHOD-RETURNING-FRT-RETAINED %s #include @@ -36,3 +42,29 @@ // CHECK-ESCAPABLE: Dumping EscapableType: // CHECK-ESCAPABLE-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct EscapableType // CHECK-ESCAPABLE: SwiftAttrAttr {{.+}} "Escapable" + +// CHECK-FUNCTION-RETURNING-FRT: Dumping functionReturningFrt__: +// CHECK-FUNCTION-RETURNING-FRT: FunctionDecl {{.+}} imported in SwiftImportAs functionReturningFrt__ 'ImmortalRefType *()' +// CHECK-FUNCTION-RETURNING-FRT-NOT: `-SwiftAttrAttr {{.+}} "returns_unretained" +// CHECK-FUNCTION-RETURNING-FRT-NOT: `-SwiftAttrAttr {{.+}} "returns_retained" + +// CHECK-FUNCTION-RETURNING-FRT-UNRETAINED: Dumping functionReturningFrt_returns_unretained: +// CHECK-FUNCTION-RETURNING-FRT-UNRETAINED: FunctionDecl {{.+}} imported in SwiftImportAs functionReturningFrt_returns_unretained 'ImmortalRefType *()' +// CHECK-FUNCTION-RETURNING-FRT-UNRETAINED: `-SwiftAttrAttr {{.+}} "returns_unretained" + +// CHECK-FUNCTION-RETURNING-FRT-RETAINED: Dumping functionReturningFrt_returns_retained: +// CHECK-FUNCTION-RETURNING-FRT-RETAINED: FunctionDecl {{.+}} imported in SwiftImportAs functionReturningFrt_returns_retained 'ImmortalRefType *()' +// CHECK-FUNCTION-RETURNING-FRT-RETAINED: `-SwiftAttrAttr {{.+}} "returns_retained" + +// CHECK-METHOD-RETURNING-FRT: Dumping ImmortalRefType::methodReturningFrt__: +// CHECK-METHOD-RETURNING-FRT: CXXMethodDecl {{.+}} imported in SwiftImportAs methodReturningFrt__ 'ImmortalRefType *()' +// CHECK-METHOD-RETURNING-FRT-NOT: `-SwiftAttrAttr {{.+}} "returns_unretained" +// CHECK-METHOD-RETURNING-FRT-NOT: `-SwiftAttrAttr {{.+}} "returns_retained" + +// CHECK-METHOD-RETURNING-FRT-UNRETAINED: Dumping ImmortalRefType::methodReturningFrt_returns_unretained: +// CHECK-METHOD-RETURNING-FRT-UNRETAINED: CXXMethodDecl {{.+}} imported in SwiftImportAs methodReturningFrt_returns_unretained 'ImmortalRefType *()' +// CHECK-METHOD-RETURNING-FRT-UNRETAINED: `-SwiftAttrAttr {{.+}} "returns_unretained" + +// CHECK-METHOD-RETURNING-FRT-RETAINED: Dumping ImmortalRefType::methodReturningFrt_returns_retained: +// CHECK-METHOD-RETURNING-FRT-RETAINED: CXXMethodDecl {{.+}} imported in SwiftImportAs methodReturningFrt_returns_retained 'ImmortalRefType *()' +// CHECK-METHOD-RETURNING-FRT-RETAINED: `-SwiftAttrAttr {{.+}} "returns_retained" diff --git a/clang/test/AST/ByteCode/builtin-bit-cast-bitfields.cpp b/clang/test/AST/ByteCode/builtin-bit-cast-bitfields.cpp index 00f465a471b0a..5aa4e256e4638 100644 --- a/clang/test/AST/ByteCode/builtin-bit-cast-bitfields.cpp +++ b/clang/test/AST/ByteCode/builtin-bit-cast-bitfields.cpp @@ -63,7 +63,7 @@ struct bytes { constexpr unsigned char operator[](size_t index) { if (index < N) - return d[index]; + return d[index]; // expected-note {{read of uninitialized object}} return -1; } }; @@ -134,18 +134,18 @@ namespace BitFields { enum byte : unsigned char {}; constexpr BF bf = {0x3}; - /// Requires bitcasts to composite types. static_assert(bit_cast>(bf).bits == bf.z); static_assert(bit_cast(bf)); - static_assert(__builtin_bit_cast(byte, bf)); + static_assert(__builtin_bit_cast(byte, bf)); // expected-error {{not an integral constant expression}} \ + // expected-note {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'byte' is invalid}} struct M { - // ref-note@+1 {{subobject declared here}} + // expected-note@+1 {{subobject declared here}} unsigned char mem[sizeof(BF)]; }; - // ref-error@+2 {{initialized by a constant expression}} - // ref-note@+1 {{not initialized}} + // expected-error@+2 {{initialized by a constant expression}} + // expected-note@+1 {{not initialized}} constexpr M m = bit_cast(bf); constexpr auto f = []() constexpr { @@ -156,8 +156,8 @@ namespace BitFields { static_assert(f()[0] + f()[1] + f()[2] == 0xc0 + 0xff + 0xee); { - // ref-error@+2 {{initialized by a constant expression}} - // ref-note@+1 {{read of uninitialized object is not allowed in a constant expression}} + // expected-error@+2 {{initialized by a constant expression}} + // expected-note@+1 {{in call to}} constexpr auto _bad = f()[3]; } @@ -173,8 +173,8 @@ namespace BitFields { }; static_assert(g().s0 + g().s1 + g().b0 + g().b1 == 0xc0 + 0xff + 0xe + 0xe); { - // ref-error@+2 {{initialized by a constant expression}} - // ref-note@+1 {{read of uninitialized object is not allowed in a constant expression}} + // expected-error@+2 {{initialized by a constant expression}} + // expected-note@+1 {{read of uninitialized object is not allowed in a constant expression}} constexpr auto _bad = g().b2; } } @@ -439,3 +439,37 @@ namespace Enums { static_assert( bit_cast((unsigned char)0x40).direction == X::direction::right); } + +namespace IndeterminateBits { + struct S { + unsigned a : 13; + unsigned : 17; + unsigned b : 2; + }; + constexpr unsigned A = __builtin_bit_cast(unsigned, S{12, 3}); // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'unsigned int' is invalid}} + + + /// GCC refuses to compile this as soon as we access the indeterminate bits + /// in the static_assert. MSVC accepts it. + struct S2 { + unsigned char a : 2; + }; + constexpr unsigned char B = __builtin_bit_cast(unsigned char, S2{3}); + static_assert(B == (LITTLE_END ? 3 : 192)); + + + + struct S3 { + unsigned a : 13; + unsigned : 17; + unsigned b : 2; + }; + + struct D { + unsigned a; + }; + constexpr D s = __builtin_bit_cast(D, S3{12, 3}); // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{indeterminate value can only initialize an object of type 'unsigned char' or 'std::byte'; 'unsigned int' is invalid}} + +} diff --git a/clang/test/AST/ByteCode/builtin-bit-cast-long-double.cpp b/clang/test/AST/ByteCode/builtin-bit-cast-long-double.cpp index 0929f7cb70b74..710612bef8fd0 100644 --- a/clang/test/AST/ByteCode/builtin-bit-cast-long-double.cpp +++ b/clang/test/AST/ByteCode/builtin-bit-cast-long-double.cpp @@ -6,7 +6,10 @@ // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple x86_64-apple-macosx10.14.0 %s -fno-signed-char -fexperimental-new-constant-interpreter // RUN: %clang_cc1 -verify=expected,both -std=c++2a -fsyntax-only -triple aarch64_be-linux-gnu %s -fexperimental-new-constant-interpreter +#if !__x86_64 // both-no-diagnostics +#endif + typedef decltype(nullptr) nullptr_t; typedef __INTPTR_TYPE__ intptr_t; @@ -35,6 +38,7 @@ 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}} @@ -49,7 +53,13 @@ static_assert(round_trip(ld), ""); static_assert(round_trip(10.0L)); -#if 0 +constexpr long double foo() { + bytes A = __builtin_bit_cast(bytes, ld); + long double ld = __builtin_bit_cast(long double, A); + return ld; +} +static_assert(foo() == ld); + constexpr bool f(bool read_uninit) { bytes b = bit_cast(ld); unsigned char ld_bytes[10] = { @@ -61,16 +71,15 @@ constexpr bool f(bool read_uninit) { if (ld_bytes[i] != b.d[i]) return false; - if (read_uninit && b.d[10]) // expected-note{{read of uninitialized object is not allowed in a constant expression}} + if (read_uninit && b.d[10]) // both-note{{read of uninitialized object is not allowed in a constant expression}} return false; return true; } static_assert(f(/*read_uninit=*/false), ""); -static_assert(f(/*read_uninit=*/true), ""); // expected-error{{static assertion expression is not an integral constant expression}} \ - // expected-note{{in call to 'f(true)'}} -#endif +static_assert(f(/*read_uninit=*/true), ""); // both-error{{static assertion expression is not an integral constant expression}} \ + // both-note{{in call to 'f(true)'}} constexpr bytes ld539 = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc0, 0x86, diff --git a/clang/test/AST/ByteCode/builtin-bit-cast.cpp b/clang/test/AST/ByteCode/builtin-bit-cast.cpp index d3935b4f921b3..8a5bef635b8fd 100644 --- a/clang/test/AST/ByteCode/builtin-bit-cast.cpp +++ b/clang/test/AST/ByteCode/builtin-bit-cast.cpp @@ -130,11 +130,13 @@ namespace simple { static_assert(check_round_trip((int)0x0C05FEFE)); static_assert(round_trip((int)0x0C05FEFE)); + static_assert(__builtin_bit_cast(intptr_t, nullptr) == 0); // both-error {{not an integral constant expression}} \ + // both-note {{indeterminate value can only initialize an object}} - /// This works in GCC and in the bytecode interpreter, but the current interpreter - /// diagnoses it. - static_assert(__builtin_bit_cast(intptr_t, nullptr) == 0); // ref-error {{not an integral constant expression}} \ - // ref-note {{indeterminate value can only initialize an object}} + constexpr int test_from_nullptr_pass = (__builtin_bit_cast(unsigned char[sizeof(nullptr)], nullptr), 0); + constexpr unsigned char NPData[sizeof(nullptr)] = {1,2,3,4}; + constexpr nullptr_t NP = __builtin_bit_cast(nullptr_t, NPData); + static_assert(NP == nullptr); } namespace Fail { @@ -388,7 +390,6 @@ void bad_types() { }; static_assert(__builtin_bit_cast(int, X{0}) == 0); // both-error {{not an integral constant expression}} \ // both-note {{bit_cast from a union type is not allowed in a constant expression}} -#if 1 struct G { int g; @@ -399,19 +400,17 @@ void bad_types() { // both-error@+2 {{constexpr variable 'x' must be initialized by a constant expression}} // both-note@+1 {{bit_cast to a union type is not allowed in a constant expression}} constexpr X x = __builtin_bit_cast(X, G{0}); -#endif + struct has_pointer { - int *ptr; // both-note {{invalid type 'int *' is a member of 'has_pointer'}} + int *ptr; // both-note 2{{invalid type 'int *' is a member of 'has_pointer'}} }; constexpr intptr_t ptr = __builtin_bit_cast(intptr_t, has_pointer{0}); // both-error {{constexpr variable 'ptr' must be initialized by a constant expression}} \ // both-note {{bit_cast from a pointer type is not allowed in a constant expression}} -#if 0 - // expected-error@+2 {{constexpr variable 'hptr' must be initialized by a constant expression}} - // expected-note@+1 {{bit_cast to a pointer type is not allowed in a constant expression}} - constexpr has_pointer hptr = __builtin_bit_cast(has_pointer, 0ul); -#endif + // both-error@+2 {{constexpr variable 'hptr' must be initialized by a constant expression}} + // both-note@+1 {{bit_cast to a pointer type is not allowed in a constant expression}} + constexpr has_pointer hptr = __builtin_bit_cast(has_pointer, (intptr_t)0); } void test_array_fill() { @@ -503,3 +502,8 @@ namespace OversizedBitField { // ref-note {{constexpr bit_cast involving bit-field is not yet supported}} #endif } + +typedef bool bool9 __attribute__((ext_vector_type(9))); +// both-error@+2 {{constexpr variable 'bad_bool9_to_short' must be initialized by a constant expression}} +// both-note@+1 {{bit_cast involving type 'bool __attribute__((ext_vector_type(9)))' (vector of 9 'bool' values) is not allowed in a constant expression; element size 1 * element count 9 is not a multiple of the byte size 8}} +constexpr unsigned short bad_bool9_to_short = __builtin_bit_cast(unsigned short, bool9{1,1,0,1,0,1,0,1,0}); diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp index e2121a54e1576..5906cb970f06c 100644 --- a/clang/test/AST/ByteCode/builtin-functions.cpp +++ b/clang/test/AST/ByteCode/builtin-functions.cpp @@ -15,6 +15,10 @@ #error "huh?" #endif +extern "C" { + typedef decltype(sizeof(int)) size_t; + extern size_t wcslen(const wchar_t *p); +} namespace strcmp { constexpr char kFoobar[6] = {'f','o','o','b','a','r'}; @@ -47,6 +51,15 @@ namespace strcmp { return __builtin_strcmp(buffer, "mutable") == 0; } static_assert(char_memchr_mutable(), ""); + + static_assert(__builtin_strncmp("abaa", "abba", 5) == -1); + static_assert(__builtin_strncmp("abaa", "abba", 4) == -1); + static_assert(__builtin_strncmp("abaa", "abba", 3) == -1); + static_assert(__builtin_strncmp("abaa", "abba", 2) == 0); + static_assert(__builtin_strncmp("abaa", "abba", 1) == 0); + static_assert(__builtin_strncmp("abaa", "abba", 0) == 0); + static_assert(__builtin_strncmp(0, 0, 0) == 0); + static_assert(__builtin_strncmp("abab\0banana", "abab\0canada", 100) == 0); } /// Copied from constant-expression-cxx11.cpp @@ -93,6 +106,14 @@ constexpr const char *a = "foo\0quux"; constexpr char d[] = { 'f', 'o', 'o' }; // no nul terminator. constexpr int bad = __builtin_strlen(d); // both-error {{constant expression}} \ // both-note {{one-past-the-end}} + + constexpr int wn = __builtin_wcslen(L"hello"); + static_assert(wn == 5); + constexpr int wm = wcslen(L"hello"); // both-error {{constant expression}} \ + // both-note {{non-constexpr function 'wcslen' cannot be used in a constant expression}} + + int arr[3]; // both-note {{here}} + int wk = arr[wcslen(L"hello")]; // both-warning {{array index 5}} } namespace nan { @@ -1176,4 +1197,92 @@ namespace BuiltinMemcpy { return b; } static_assert(simpleMove() == 12); + + constexpr int memcpyTypeRem() { // both-error {{never produces a constant expression}} + int a = 12; + int b = 0; + __builtin_memmove(&b, &a, 1); // both-note {{'memmove' not supported: size to copy (1) is not a multiple of size of element type 'int'}} \ + // both-note {{not supported}} + return b; + } + static_assert(memcpyTypeRem() == 12); // both-error {{not an integral constant expression}} \ + // both-note {{in call to}} + + template + constexpr T result(T (&arr)[4]) { + return arr[0] * 1000 + arr[1] * 100 + arr[2] * 10 + arr[3]; + } + + constexpr int test_memcpy(int a, int b, int n) { + int arr[4] = {1, 2, 3, 4}; + __builtin_memcpy(arr + a, arr + b, n); // both-note {{overlapping memory regions}} + return result(arr); + } + + static_assert(test_memcpy(1, 2, sizeof(int)) == 1334); + static_assert(test_memcpy(0, 1, sizeof(int) * 2) == 2334); // both-error {{not an integral constant expression}} \ + // both-note {{in call}} +} + +namespace Memcmp { + constexpr unsigned char ku00fe00[] = {0x00, 0xfe, 0x00}; + constexpr unsigned char ku00feff[] = {0x00, 0xfe, 0xff}; + constexpr signed char ks00fe00[] = {0, -2, 0}; + constexpr signed char ks00feff[] = {0, -2, -1}; + static_assert(__builtin_memcmp(ku00feff, ks00fe00, 2) == 0); + static_assert(__builtin_memcmp(ku00feff, ks00fe00, 99) == 1); + static_assert(__builtin_memcmp(ku00fe00, ks00feff, 99) == -1); + static_assert(__builtin_memcmp(ks00feff, ku00fe00, 2) == 0); + static_assert(__builtin_memcmp(ks00feff, ku00fe00, 99) == 1); + static_assert(__builtin_memcmp(ks00fe00, ku00feff, 99) == -1); + static_assert(__builtin_memcmp(ks00fe00, ks00feff, 2) == 0); + static_assert(__builtin_memcmp(ks00feff, ks00fe00, 99) == 1); + static_assert(__builtin_memcmp(ks00fe00, ks00feff, 99) == -1); + + struct Bool3Tuple { bool bb[3]; }; + constexpr Bool3Tuple kb000100 = {{false, true, false}}; + static_assert(sizeof(bool) != 1u || __builtin_memcmp(ks00fe00, kb000100.bb, 1) == 0); // both-error {{constant}} \ + // both-note {{not supported}} + + constexpr char a = 'a'; + constexpr char b = 'a'; + static_assert(__builtin_memcmp(&a, &b, 1) == 0); + + extern struct Incomplete incomplete; + static_assert(__builtin_memcmp(&incomplete, "", 0u) == 0); + static_assert(__builtin_memcmp("", &incomplete, 0u) == 0); + static_assert(__builtin_memcmp(&incomplete, "", 1u) == 42); // both-error {{not an integral constant}} \ + // both-note {{not supported}} + static_assert(__builtin_memcmp("", &incomplete, 1u) == 42); // both-error {{not an integral constant}} \ + // both-note {{not supported}} + + static_assert(__builtin_memcmp(u8"abab\0banana", u8"abab\0banana", 100) == 0); // both-error {{not an integral constant}} \ + // both-note {{dereferenced one-past-the-end}} + + static_assert(__builtin_bcmp("abaa", "abba", 3) != 0); + static_assert(__builtin_bcmp("abaa", "abba", 2) == 0); + static_assert(__builtin_bcmp("a\203", "a", 2) != 0); + static_assert(__builtin_bcmp("a\203", "a\003", 2) != 0); + static_assert(__builtin_bcmp(0, 0, 0) == 0); + static_assert(__builtin_bcmp("abab\0banana", "abab\0banana", 100) == 0); // both-error {{not an integral constant}}\ + // both-note {{dereferenced one-past-the-end}} + static_assert(__builtin_bcmp("abab\0banana", "abab\0canada", 100) != 0); // FIXME: Should we reject this? + static_assert(__builtin_bcmp("abab\0banana", "abab\0canada", 7) != 0); + static_assert(__builtin_bcmp("abab\0banana", "abab\0canada", 6) != 0); + static_assert(__builtin_bcmp("abab\0banana", "abab\0canada", 5) == 0); + + + static_assert(__builtin_wmemcmp(L"abaa", L"abba", 3) == -1); + static_assert(__builtin_wmemcmp(L"abaa", L"abba", 2) == 0); + static_assert(__builtin_wmemcmp(0, 0, 0) == 0); +#if __WCHAR_WIDTH__ == 32 + static_assert(__builtin_wmemcmp(L"a\x83838383", L"aa", 2) == + (wchar_t)-1U >> 31); +#endif + static_assert(__builtin_wmemcmp(L"abab\0banana", L"abab\0banana", 100) == 0); // both-error {{not an integral constant}} \ + // both-note {{dereferenced one-past-the-end}} + static_assert(__builtin_wmemcmp(L"abab\0banana", L"abab\0canada", 100) == -1); // FIXME: Should we reject this? + static_assert(__builtin_wmemcmp(L"abab\0banana", L"abab\0canada", 7) == -1); + static_assert(__builtin_wmemcmp(L"abab\0banana", L"abab\0canada", 6) == -1); + static_assert(__builtin_wmemcmp(L"abab\0banana", L"abab\0canada", 5) == 0); } diff --git a/clang/test/AST/ByteCode/complex.cpp b/clang/test/AST/ByteCode/complex.cpp index ee11c6214b70c..2c0111c53d3bf 100644 --- a/clang/test/AST/ByteCode/complex.cpp +++ b/clang/test/AST/ByteCode/complex.cpp @@ -146,11 +146,6 @@ constexpr _Complex int I3 = {15}; static_assert(__real(I3) == 15, ""); static_assert(__imag(I3) == 0, ""); -constexpr _Complex _BitInt(8) A = {4}; -static_assert(__real(A) == 4, ""); -static_assert(__imag(A) == 0, ""); - - constexpr _Complex double Doubles[4] = {{1.0, 2.0}}; static_assert(__real(Doubles[0]) == 1.0, ""); static_assert(__imag(Doubles[0]) == 2.0, ""); @@ -163,9 +158,6 @@ static_assert(__imag(Doubles[3]) == 0.0, ""); static_assert(~(0.5 + 1.5j) == (0.5 + -1.5j), ""); -static_assert(__extension__ __imag(A) == 0, ""); -static_assert(__imag(__extension__ A) == 0, ""); - void func(void) { __complex__ int arr; _Complex int result; diff --git a/clang/test/AST/ByteCode/shifts.cpp b/clang/test/AST/ByteCode/shifts.cpp index 0b3383731c677..f02aaf004cbd6 100644 --- a/clang/test/AST/ByteCode/shifts.cpp +++ b/clang/test/AST/ByteCode/shifts.cpp @@ -1,7 +1,9 @@ // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++20 -verify=expected,all %s // RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=cxx17,all %s +// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=cxx17,all -triple armv8 %s // RUN: %clang_cc1 -std=c++20 -verify=ref,all %s // RUN: %clang_cc1 -std=c++17 -verify=ref-cxx17,all %s +// RUN: %clang_cc1 -std=c++17 -verify=ref-cxx17,all -triple armv8 %s #define INT_MIN (~__INT_MAX__) @@ -21,27 +23,15 @@ namespace shifts { c = 1 << 0; c = 1 << -0; c = 1 >> -0; - c = 1 << -1; // expected-warning {{shift count is negative}} \ - // expected-note {{negative shift count -1}} \ - // cxx17-note {{negative shift count -1}} \ - // cxx17-warning {{shift count is negative}} \ - // ref-warning {{shift count is negative}} \ - // ref-note {{negative shift count -1}} \ - // ref-cxx17-warning {{shift count is negative}} \ - // ref-cxx17-note {{negative shift count -1}} + c = 1 << -1; // all-warning {{shift count is negative}} \ + // all-note {{negative shift count -1}} c = 1 >> -1; // expected-warning {{shift count is negative}} \ // cxx17-warning {{shift count is negative}} \ // ref-warning {{shift count is negative}} \ // ref-cxx17-warning {{shift count is negative}} - c = 1 << (unsigned)-1; // expected-warning {{shift count >= width of type}} \ - // expected-warning {{implicit conversion from 'int' to 'char' changes value from -2147483648 to 0}} \ - // cxx17-warning {{shift count >= width of type}} \ - // cxx17-warning {{implicit conversion from 'int' to 'char' changes value from -2147483648 to 0}} \ - // ref-warning {{shift count >= width of type}} \ - // ref-warning {{implicit conversion from 'int' to 'char' changes value from -2147483648 to 0}} \ - // ref-cxx17-warning {{shift count >= width of type}} \ - // ref-cxx17-warning {{implicit conversion from 'int' to 'char' changes value from -2147483648 to 0}} + c = 1 << (unsigned)-1; // all-warning {{shift count >= width of type}} \ + // all-warning {{implicit conversion from 'int' to 'char' changes value from -2147483648 to 0}} c = 1 >> (unsigned)-1; // expected-warning {{shift count >= width of type}} \ // cxx17-warning {{shift count >= width of type}} \ // ref-warning {{shift count >= width of type}} \ @@ -212,3 +202,28 @@ enum shiftof { X3 = (1<<32) // all-error {{expression is not an integral constant expression}} \ // all-note {{shift count 32 >= width of type 'int'}} }; + +#if __WCHAR_WIDTH__ == 32 +# if !defined(__WCHAR_UNSIGNED__) +static_assert(((wchar_t)-1U >> 31) == -1); +# else +static_assert(((wchar_t)-1U >> 31) == 1); +# endif +#endif + +#if __INT_WIDTH__ == 32 +static_assert(((int)-1U >> 32) == -1); // all-error {{not an integral constant expression}} \ + // all-note {{shift count 32 >= width of type 'int' (32 bits)}} +#endif + +static_assert((-4 << 32) == 0); // all-error {{not an integral constant expression}} \ + // all-note {{shift count}} + +static_assert((-4 << 1) == -8); // ref-cxx17-error {{not an integral constant expression}} \ + // ref-cxx17-note {{left shift of negative value -4}} \ + // cxx17-error {{not an integral constant expression}} \ + // cxx17-note {{left shift of negative value -4}} +static_assert((-4 << 31) == 0); // ref-cxx17-error {{not an integral constant expression}} \ + // ref-cxx17-note {{left shift of negative value -4}} \ + // cxx17-error {{not an integral constant expression}} \ + // cxx17-note {{left shift of negative value -4}} diff --git a/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl new file mode 100644 index 0000000000000..909cce17e344c --- /dev/null +++ b/clang/test/AST/HLSL/ByteAddressBuffers-AST.hlsl @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ +// RUN: -DRESOURCE=ByteAddressBuffer %s | FileCheck -DRESOURCE=ByteAddressBuffer \ +// RUN: -check-prefix=EMPTY %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ +// RUN: -DRESOURCE=ByteAddressBuffer %s | FileCheck -DRESOURCE=ByteAddressBuffer \ +// RUN: -check-prefixes=CHECK,CHECK-SRV,CHECK-NOSUBSCRIPT %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ +// RUN: -DRESOURCE=RWByteAddressBuffer %s | FileCheck -DRESOURCE=RWByteAddressBuffer \ +// RUN: -check-prefix=EMPTY %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ +// RUN: -DRESOURCE=RWByteAddressBuffer %s | FileCheck -DRESOURCE=RWByteAddressBuffer \ +// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ +// RUN: -DRESOURCE=RasterizerOrderedByteAddressBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedByteAddressBuffer \ +// RUN: -check-prefix=EMPTY %s +// +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ +// RUN: -DRESOURCE=RasterizerOrderedByteAddressBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedByteAddressBuffer \ +// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT %s + +// EMPTY: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <> implicit class [[RESOURCE]] +// EMPTY-NEXT: FinalAttr 0x{{[0-9A-Fa-f]+}} <> Implicit final + +// There should be no more occurrences of RESOURCE +// EMPTY-NOT: {{[^[:alnum:]]}}[[RESOURCE]] + +#ifndef EMPTY + +RESOURCE Buffer; + +#endif + +// CHECK: CXXRecordDecl 0x{{[0-9A-Fa-f]+}} <> implicit referenced class [[RESOURCE]] definition + + +// CHECK: FinalAttr 0x{{[0-9A-Fa-f]+}} <> Implicit final +// CHECK-NEXT: FieldDecl 0x{{[0-9A-Fa-f]+}} <> implicit __handle '__hlsl_resource_t +// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]] +// CHECK-UAV-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(char8_t)]] +// CHECK-NEXT: HLSLResourceAttr 0x{{[0-9A-Fa-f]+}} <> Implicit RawBuffer + +// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> operator[] 'const element_type &(unsigned int) const' +// CHECK-NOSUBSCRIPT-NOT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> operator[] 'element_type &(unsigned int)' diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl index afee0e120afdb..6cb4379ef5f55 100644 --- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl @@ -20,7 +20,7 @@ // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ // RUN: -DRESOURCE=AppendStructuredBuffer %s | FileCheck -DRESOURCE=AppendStructuredBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT %s +// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT,CHECK-APPEND %s // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ // RUN: -DRESOURCE=ConsumeStructuredBuffer %s | FileCheck -DRESOURCE=ConsumeStructuredBuffer \ @@ -28,7 +28,7 @@ // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump \ // RUN: -DRESOURCE=ConsumeStructuredBuffer %s | FileCheck -DRESOURCE=ConsumeStructuredBuffer \ -// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT %s +// RUN: -check-prefixes=CHECK,CHECK-UAV,CHECK-NOSUBSCRIPT,CHECK-CONSUME %s // // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-library -x hlsl -ast-dump -DEMPTY \ // RUN: -DRESOURCE=RasterizerOrderedStructuredBuffer %s | FileCheck -DRESOURCE=RasterizerOrderedStructuredBuffer \ @@ -135,6 +135,48 @@ RESOURCE Buffer; // CHECK-COUNTER-NEXT: IntegerLiteral 0x{{[0-9A-Fa-f]+}} <> 'int' -1 // CHECK-COUNTER-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline +// CHECK-APPEND: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> Append 'void (element_type)' +// CHECK-APPEND-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <> value 'element_type' +// CHECK-APPEND-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-APPEND-NEXT: BinaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' '=' +// CHECK-APPEND-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow +// CHECK-APPEND-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' +// CHECK-APPEND-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// CHECK-APPEND-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-APPEND-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this +// CHECK-APPEND-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' +// CHECK-APPEND-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept' +// CHECK-APPEND-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-APPEND-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-APPEND-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this +// CHECK-APPEND-NEXT: IntegerLiteral 0x{{[0-9A-Fa-f]+}} <> 'int' 1 +// CHECK-APPEND-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type' ParmVar 0x{{[0-9A-Fa-f]+}} 'value' 'element_type' + +// CHECK-CONSUME: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> Consume 'element_type ()' +// CHECK-CONSUME-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-CONSUME-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-CONSUME-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow +// CHECK-CONSUME-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' +// CHECK-CONSUME-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// CHECK-CONSUME-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-CONSUME-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this +// CHECK-CONSUME-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' +// CHECK-CONSUME-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept' +// CHECK-CONSUME-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::raw_buffer]] +// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle +// CHECK-CONSUME-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this +// CHECK-CONSUME-NEXT: IntegerLiteral 0x{{[0-9A-Fa-f]+}} <> 'int' -1 + // CHECK: ClassTemplateSpecializationDecl 0x{{[0-9A-Fa-f]+}} <> class [[RESOURCE]] definition // CHECK: TemplateArgument type 'float' diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl index 6bab39de5a233..d6dfb0caba5d9 100644 --- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl +++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl @@ -87,6 +87,21 @@ RESOURCE Buffer; // CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int' // CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline +// CHECK-NEXT: CXXMethodDecl 0x{{[0-9A-Fa-f]+}} <> Load 'element_type (unsigned int)' +// CHECK-NEXT: ParmVarDecl 0x{{[0-9A-Fa-f]+}} <> Index 'unsigned int' +// CHECK-NEXT: CompoundStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-NEXT: ReturnStmt 0x{{[0-9A-Fa-f]+}} <> +// CHECK-NEXT: UnaryOperator 0x{{[0-9A-Fa-f]+}} <> 'element_type' prefix '*' cannot overflow +// CHECK-NEXT: CallExpr 0x{{[0-9A-Fa-f]+}} <> 'element_type *' +// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> '' Function 0x{{[0-9A-Fa-f]+}} '__builtin_hlsl_resource_getpointer' 'void (...) noexcept' +// CHECK-NEXT: MemberExpr 0x{{[0-9A-Fa-f]+}} <> '__hlsl_resource_t +// CHECK-SAME{LITERAL}: [[hlsl::resource_class(UAV)]] +// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]] +// CHECK-SAME: ' lvalue .__handle 0x{{[0-9A-Fa-f]+}} +// CHECK-NEXT: CXXThisExpr 0x{{[0-9A-Fa-f]+}} <> '[[RESOURCE]]' lvalue implicit this +// CHECK-NEXT: DeclRefExpr 0x{{[0-9A-Fa-f]+}} <> 'unsigned int' ParmVar 0x{{[0-9A-Fa-f]+}} 'Index' 'unsigned int' +// CHECK-NEXT: AlwaysInlineAttr 0x{{[0-9A-Fa-f]+}} <> Implicit always_inline + // CHECK: ClassTemplateSpecializationDecl 0x{{[0-9A-Fa-f]+}} <> class [[RESOURCE]] definition // CHECK: TemplateArgument type 'float' diff --git a/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp b/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp index 04cff07376885..1b385e0fc3331 100644 --- a/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp +++ b/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp @@ -9,7 +9,7 @@ int main() { S s; int x = s.f(); // CHECK: CallExpr 0x{{[^ ]*}} 'int - // CHECK-NEXT: |-ImplicitCastExpr 0x{{[^ ]*}} 'int (*)(S &)' - // CHECK-NEXT: | `-DeclRefExpr 0x{{[^ ]*}} 'int (S &)' lvalue CXXMethod 0x{{[^ ]*}} 'f' 'int (S &)' + // CHECK-NEXT: |-ImplicitCastExpr 0x{{[^ ]*}} 'int (*)(S &)' + // CHECK-NEXT: | `-DeclRefExpr 0x{{[^ ]*}} 'int (S &)' lvalue CXXMethod 0x{{[^ ]*}} 'f' 'int (S &)' } } diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp index 4388462224026..b59fa3778192f 100644 --- a/clang/test/AST/ast-dump-recovery.cpp +++ b/clang/test/AST/ast-dump-recovery.cpp @@ -480,3 +480,37 @@ void RecoveryForStmtCond() { // CHECK-NEXT: `-CompoundStmt {{.*}} for (int i = 0; i < invalid; ++i) {} } + +// Fix crash issue https://github.com/llvm/llvm-project/issues/112560. +// Make sure clang compiles the following code without crashing: + +// CHECK:NamespaceDecl {{.*}} GH112560 +// CHECK-NEXT: |-CXXRecordDecl {{.*}} referenced union U definition +// CHECK-NEXT: | |-DefinitionData {{.*}} +// CHECK-NEXT: | | |-DefaultConstructor {{.*}} +// CHECK-NEXT: | | |-CopyConstructor {{.*}} +// CHECK-NEXT: | | |-MoveConstructor {{.*}} +// CHECK-NEXT: | | |-CopyAssignment {{.*}} +// CHECK-NEXT: | | |-MoveAssignment {{.*}} +// CHECK-NEXT: | | `-Destructor {{.*}} +// CHECK-NEXT: | |-CXXRecordDecl {{.*}} implicit union U +// CHECK-NEXT: | `-FieldDecl {{.*}} invalid f 'int' +// CHECK-NEXT: | `-RecoveryExpr {{.*}} 'int' contains-errors +// DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors +namespace GH112560 { +union U { + int f = ; +}; + +// CHECK: FunctionDecl {{.*}} foo 'void ()' +// CHECK-NEXT: `-CompoundStmt {{.*}} +// CHECK-NEXT: `-DeclStmt {{.*}} +// CHECK-NEXT: `-VarDecl {{.*}} g 'U':'GH112560::U' listinit +// CHECK-NEXT: `-InitListExpr {{.*}} 'U':'GH112560::U' contains-errors field Field {{.*}} 'f' 'int' +// CHECK-NEXT: `-CXXDefaultInitExpr {{.*}} 'int' contains-errors has rewritten init +// CHECK-NEXT: `-RecoveryExpr {{.*}} 'int' contains-errors +// DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors +void foo() { + U g{}; +} +} // namespace GH112560 diff --git a/clang/test/AST/ast-dump-types-json.cpp b/clang/test/AST/ast-dump-types-json.cpp index c1bb9266fa869..fa1fb53df0e85 100644 --- a/clang/test/AST/ast-dump-types-json.cpp +++ b/clang/test/AST/ast-dump-types-json.cpp @@ -248,15 +248,24 @@ using ::TestUsingShadowDeclType; // CHECK-NEXT: "inner": [ // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", -// CHECK-NEXT: "kind": "RecordType", +// CHECK-NEXT: "kind": "ElaboratedType", // CHECK-NEXT: "type": { // CHECK-NEXT: "qualType": "T" // CHECK-NEXT: }, -// CHECK-NEXT: "decl": { -// CHECK-NEXT: "id": "0x{{.*}}", -// CHECK-NEXT: "kind": "CXXRecordDecl", -// CHECK-NEXT: "name": "T" -// CHECK-NEXT: } +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "RecordType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "T" +// CHECK-NEXT: }, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXRecordDecl", +// CHECK-NEXT: "name": "T" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", @@ -325,15 +334,24 @@ using ::TestUsingShadowDeclType; // CHECK-NEXT: "inner": [ // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", -// CHECK-NEXT: "kind": "RecordType", +// CHECK-NEXT: "kind": "ElaboratedType", // CHECK-NEXT: "type": { // CHECK-NEXT: "qualType": "T" // CHECK-NEXT: }, -// CHECK-NEXT: "decl": { -// CHECK-NEXT: "id": "0x{{.*}}", -// CHECK-NEXT: "kind": "CXXRecordDecl", -// CHECK-NEXT: "name": "T" -// CHECK-NEXT: } +// CHECK-NEXT: "inner": [ +// CHECK-NEXT: { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "RecordType", +// CHECK-NEXT: "type": { +// CHECK-NEXT: "qualType": "T" +// CHECK-NEXT: }, +// CHECK-NEXT: "decl": { +// CHECK-NEXT: "id": "0x{{.*}}", +// CHECK-NEXT: "kind": "CXXRecordDecl", +// CHECK-NEXT: "name": "T" +// CHECK-NEXT: } +// CHECK-NEXT: } +// CHECK-NEXT: ] // CHECK-NEXT: }, // CHECK-NEXT: { // CHECK-NEXT: "id": "0x{{.*}}", diff --git a/clang/test/AST/ast-print-openacc-combined-construct.cpp b/clang/test/AST/ast-print-openacc-combined-construct.cpp index 435c770c7457d..25fa29cbbe04e 100644 --- a/clang/test/AST/ast-print-openacc-combined-construct.cpp +++ b/clang/test/AST/ast-print-openacc-combined-construct.cpp @@ -242,4 +242,175 @@ void foo() { #pragma acc parallel loop vector_length((int)array[1]) for(int i = 0;i<5;++i); +// CHECK: #pragma acc parallel loop gang(dim: 2) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc parallel loop gang(dim:2) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc serial loop gang(static: i) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc serial loop gang(static:i) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc parallel loop gang(static: i) gang(dim: 2) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc parallel loop gang(static:i) gang(dim:2) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc parallel loop gang(static: i, dim: 2) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc parallel loop gang(static:i, dim:2) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc parallel loop gang(dim: 2) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc parallel loop gang(dim:2) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc parallel loop gang(static: i) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc parallel loop gang(static:i) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc parallel loop gang(static: i) gang(dim: 2) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc parallel loop gang(static:i) gang(dim:2) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc parallel loop gang(static: i, dim: 2) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc parallel loop gang(static:i, dim:2) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc kernels loop gang(num: i) gang(static: i) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc kernels loop gang(i) gang(static:i) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc kernels loop gang(num: i) gang(static: i) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc kernels loop gang(num:i) gang(static:i) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc serial loop gang(static: i) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc serial loop gang(static:i) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc serial loop gang(static: *) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc serial loop gang(static:*) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc parallel loop worker +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc parallel loop worker + for(int i = 0;i<5;++i); + +// CHECK-NEXT: #pragma acc parallel loop worker +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc parallel loop worker + for(int i = 0;i<5;++i); + +// CHECK-NEXT: #pragma acc serial loop worker +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc serial loop worker + for(int i = 0;i<5;++i); + +// CHECK-NEXT: #pragma acc kernels loop worker(num: 5) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc kernels loop worker(5) + for(int i = 0;i<5;++i); + +// CHECK-NEXT: #pragma acc kernels loop worker(num: 5) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc kernels loop worker(num:5) + for(int i = 0;i<5;++i); + + // CHECK: #pragma acc parallel loop vector +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc parallel loop vector + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc parallel loop vector(length: 5) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc parallel loop vector(5) + for(int i = 0;i<5;++i); + +// CHECK: #pragma acc parallel loop vector(length: 5) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc parallel loop vector(length:5) + for(int i = 0;i<5;++i); + +// CHECK-NEXT: #pragma acc kernels loop vector +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc kernels loop vector + for(int i = 0;i<5;++i); + +// CHECK-NEXT: #pragma acc kernels loop vector(length: 5) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc kernels loop vector(5) + for(int i = 0;i<5;++i); + +// CHECK-NEXT: #pragma acc kernels loop vector(length: 5) +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc kernels loop vector(length:5) + for(int i = 0;i<5;++i); + +// CHECK-NEXT: #pragma acc serial loop vector +// CHECK-NEXT: for (int i = 0; i < 5; ++i) +// CHECK-NEXT: ; +#pragma acc serial loop vector + for(int i = 0;i<5;++i); + +//CHECK: #pragma acc parallel loop reduction(+: iPtr) +#pragma acc parallel loop reduction(+: iPtr) + for(int i = 0;i<5;++i); +//CHECK: #pragma acc serial loop reduction(*: i) +#pragma acc serial loop reduction(*: i) + for(int i = 0;i<5;++i); +//CHECK: #pragma acc kernels loop reduction(max: SomeB) +#pragma acc kernels loop reduction(max: SomeB) + for(int i = 0;i<5;++i); +//CHECK: #pragma acc parallel loop reduction(min: iPtr) +#pragma acc parallel loop reduction(min: iPtr) + for(int i = 0;i<5;++i); +//CHECK: #pragma acc serial loop reduction(&: i) +#pragma acc serial loop reduction(&: i) + for(int i = 0;i<5;++i); +//CHECK: #pragma acc kernels loop reduction(|: SomeB) +#pragma acc kernels loop reduction(|: SomeB) + for(int i = 0;i<5;++i); +//CHECK: #pragma acc parallel loop reduction(^: iPtr) +#pragma acc parallel loop reduction(^: iPtr) + for(int i = 0;i<5;++i); +//CHECK: #pragma acc serial loop reduction(&&: i) +#pragma acc serial loop reduction(&&: i) + for(int i = 0;i<5;++i); +//CHECK: #pragma acc kernels loop reduction(||: SomeB) +#pragma acc kernels loop reduction(||: SomeB) + for(int i = 0;i<5;++i); } diff --git a/clang/test/AST/ast-print-openacc-data-construct.cpp b/clang/test/AST/ast-print-openacc-data-construct.cpp new file mode 100644 index 0000000000000..f568ae5ce6346 --- /dev/null +++ b/clang/test/AST/ast-print-openacc-data-construct.cpp @@ -0,0 +1,132 @@ +// RUN: %clang_cc1 -fopenacc -Wno-openacc-deprecated-clause-alias -Wno-source-uses-openacc -ast-print %s -o - | FileCheck %s + +void foo() { + int Var; + // TODO OpenACC: These are only legal if they have one of a list of clauses on + // them, so the 'check' lines should start to include those once we implement + // them. For now, they don't emit those because they are 'not implemented'. + +// CHECK: #pragma acc data default(none) +#pragma acc data default(none) + ; + +// CHECK: #pragma acc data default(none) device_type(int) +#pragma acc data default(none) device_type(int) + ; + +// CHECK: #pragma acc enter data copyin(Var) +#pragma acc enter data copyin(Var) + ; +// CHECK: #pragma acc exit data copyout(Var) +#pragma acc exit data copyout(Var) + ; +// CHECK: #pragma acc host_data use_device(Var) +#pragma acc host_data use_device(Var) + ; + + int i; + int *iPtr; + int array[5]; + +// CHECK: #pragma acc data default(none) if(i == array[1]) +#pragma acc data default(none) if(i == array[1]) + ; +// CHECK: #pragma acc enter data copyin(Var) if(i == array[1]) +#pragma acc enter data copyin(Var) if(i == array[1]) + ; +// CHECK: #pragma acc exit data copyout(Var) if(i == array[1]) +#pragma acc exit data copyout(Var) if(i == array[1]) + ; +// CHECK: #pragma acc host_data use_device(Var) if(i == array[1]) +#pragma acc host_data use_device(Var) if(i == array[1]) + ; + +// CHECK: #pragma acc data default(none) async(i) +#pragma acc data default(none) async(i) + ; +// CHECK: #pragma acc enter data copyin(i) async(i) +#pragma acc enter data copyin(i) async(i) +// CHECK: #pragma acc exit data copyout(i) async +#pragma acc exit data copyout(i) async + +// CHECK: #pragma acc data default(none) wait +#pragma acc data default(none) wait() + ; + +// CHECK: #pragma acc enter data copyin(Var) wait() +#pragma acc enter data copyin(Var) wait() + +// CHECK: #pragma acc exit data copyout(Var) wait(*iPtr, i) +#pragma acc exit data copyout(Var) wait(*iPtr, i) + +// CHECK: #pragma acc data default(none) wait(queues: *iPtr, i) +#pragma acc data default(none) wait(queues:*iPtr, i) + ; + +// CHECK: #pragma acc enter data copyin(Var) wait(devnum: i : *iPtr, i) +#pragma acc enter data copyin(Var) wait(devnum:i:*iPtr, i) + +// CHECK: #pragma acc exit data copyout(Var) wait(devnum: i : queues: *iPtr, i) +#pragma acc exit data copyout(Var) wait(devnum:i:queues:*iPtr, i) + +// CHECK: #pragma acc data default(none) +#pragma acc data default(none) + ; + +// CHECK: #pragma acc data default(present) +#pragma acc data default(present) + ; + +// CHECK: #pragma acc data default(none) no_create(i, array[1], array, array[1:2]) +#pragma acc data default(none) no_create(i, array[1], array, array[1:2]) + ; + +// CHECK: #pragma acc data default(none) no_create(i, array[1], array, array[1:2]) present(i, array[1], array, array[1:2]) +#pragma acc data default(none) no_create(i, array[1], array, array[1:2]) present(i, array[1], array, array[1:2]) + ; +// CHECK: #pragma acc data present(i, array[1], array, array[1:2]) +#pragma acc data present(i, array[1], array, array[1:2]) + ; + +// CHECK: #pragma acc data default(none) copy(i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(i, array[1], array, array[1:2]) +#pragma acc data default(none) copy(i, array[1], array, array[1:2]) pcopy(i, array[1], array, array[1:2]) present_or_copy(i, array[1], array, array[1:2]) + ; + +// CHECK: #pragma acc enter data copyin(i, array[1], array, array[1:2]) pcopyin(readonly: i, array[1], array, array[1:2]) present_or_copyin(i, array[1], array, array[1:2]) +#pragma acc enter data copyin(i, array[1], array, array[1:2]) pcopyin(readonly:i, array[1], array, array[1:2]) present_or_copyin(i, array[1], array, array[1:2]) + +// CHECK: #pragma acc exit data copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(i, array[1], array, array[1:2]) +#pragma acc exit data copyout(i, array[1], array, array[1:2]) pcopyout(zero: i, array[1], array, array[1:2]) present_or_copyout(i, array[1], array, array[1:2]) + +// CHECK: #pragma acc enter data create(i, array[1], array, array[1:2]) pcreate(zero: i, array[1], array, array[1:2]) present_or_create(i, array[1], array, array[1:2]) +#pragma acc enter data create(i, array[1], array, array[1:2]) pcreate(zero: i, array[1], array, array[1:2]) present_or_create(i, array[1], array, array[1:2]) + + float *arrayPtr[5]; + +// CHECK: #pragma acc data default(none) deviceptr(iPtr, arrayPtr[0]) +#pragma acc data default(none) deviceptr(iPtr, arrayPtr[0]) + +// CHECK: #pragma acc data default(none) attach(iPtr, arrayPtr[0]) +#pragma acc data default(none) attach(iPtr, arrayPtr[0]) + ; + +// CHECK: #pragma acc exit data copyout(i) finalize +#pragma acc exit data copyout(i) finalize + +// CHECK: #pragma acc host_data use_device(i) if_present +#pragma acc host_data use_device(i) if_present + ; +// CHECK: #pragma acc exit data copyout(i) detach(iPtr, arrayPtr[0]) +#pragma acc exit data copyout(i) detach(iPtr, arrayPtr[0]) + +// CHECK: #pragma acc exit data copyout(i) delete(i, array[1], array, array[1:2]) +#pragma acc exit data copyout(i) delete(i, array[1], array, array[1:2]) + ; + +// CHECK: #pragma acc exit data copyout(i) delete(i, array[1], array, array[1:2]) +#pragma acc exit data copyout(i) delete(i, array[1], array, array[1:2]) + +// CHECK: #pragma acc host_data use_device(i) +#pragma acc host_data use_device(i) + ; +} diff --git a/clang/test/AST/ms-constexpr-new.cpp b/clang/test/AST/ms-constexpr-new.cpp new file mode 100644 index 0000000000000..4b534cf020764 --- /dev/null +++ b/clang/test/AST/ms-constexpr-new.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -fms-compatibility -fms-compatibility-version=19.33 -std=c++20 -ast-dump %s | FileCheck %s + +// CHECK: used operator new +// CHECK: MSConstexprAttr 0x{{[0-9a-f]+}} +[[nodiscard]] [[msvc::constexpr]] inline void* __cdecl operator new(decltype(sizeof(void*)), void* p) noexcept { return p; } + +// CHECK: used constexpr construct_at +// CHECK: AttributedStmt 0x{{[0-9a-f]+}} +// CHECK-NEXT: MSConstexprAttr 0x{{[0-9a-f]+}} +// CHECK-NEXT: ReturnStmt 0x{{[0-9a-f]+}} +constexpr int* construct_at(int* p, int v) { [[msvc::constexpr]] return ::new (p) int(v); } +constexpr bool check_construct_at() { int x; return *construct_at(&x, 42) == 42; } +static_assert(check_construct_at()); diff --git a/clang/test/Analysis/Checkers/WebKit/call-args-checked-const-member.cpp b/clang/test/Analysis/Checkers/WebKit/call-args-checked-const-member.cpp index 76f80a12c1703..f7095606c77a4 100644 --- a/clang/test/Analysis/Checkers/WebKit/call-args-checked-const-member.cpp +++ b/clang/test/Analysis/Checkers/WebKit/call-args-checked-const-member.cpp @@ -49,15 +49,44 @@ class Foo { Foo(); void bar(); + CheckedObj& ensureObj3() { + if (!m_obj3) + const_cast&>(m_obj3) = new CheckedObj; + return *m_obj3; + } + + CheckedObj& badEnsureObj4() { + if (!m_obj4) + const_cast&>(m_obj4) = new CheckedObj; + if (auto* next = m_obj4->next()) + return *next; + return *m_obj4; + } + + CheckedObj* ensureObj5() { + if (!m_obj5) + const_cast&>(m_obj5) = new CheckedObj; + if (m_obj5->next()) + return nullptr; + return m_obj5.get(); + } + private: const std::unique_ptr m_obj1; std::unique_ptr m_obj2; + const std::unique_ptr m_obj3; + const std::unique_ptr m_obj4; + const std::unique_ptr m_obj5; }; void Foo::bar() { m_obj1->method(); m_obj2->method(); // expected-warning@-1{{Call argument for 'this' parameter is unchecked and unsafe}} + ensureObj3().method(); + badEnsureObj4().method(); + // expected-warning@-1{{Call argument for 'this' parameter is unchecked and unsafe}} + ensureObj5()->method(); } } // namespace call_args_const_unique_ptr diff --git a/clang/test/Analysis/Checkers/WebKit/call-args-checked-ptr.cpp b/clang/test/Analysis/Checkers/WebKit/call-args-checked-ptr.cpp index 072bceedcf961..59f247d6d007c 100644 --- a/clang/test/Analysis/Checkers/WebKit/call-args-checked-ptr.cpp +++ b/clang/test/Analysis/Checkers/WebKit/call-args-checked-ptr.cpp @@ -117,7 +117,7 @@ namespace null_ptr { namespace ref_counted_lookalike { struct Decoy { - CheckedObj* get() { return nullptr; } + CheckedObj* get(); }; void foo() { diff --git a/clang/test/Analysis/Checkers/WebKit/call-args-counted-const-member.cpp b/clang/test/Analysis/Checkers/WebKit/call-args-counted-const-member.cpp index b3296507a5c92..215238a7fcf07 100644 --- a/clang/test/Analysis/Checkers/WebKit/call-args-counted-const-member.cpp +++ b/clang/test/Analysis/Checkers/WebKit/call-args-counted-const-member.cpp @@ -52,15 +52,44 @@ class Foo { Foo(); void bar(); + RefCountable& ensureObj3() { + if (!m_obj3) + const_cast&>(m_obj3) = RefCountable::makeUnique(); + return *m_obj3; + } + + RefCountable& badEnsureObj4() { + if (!m_obj4) + const_cast&>(m_obj4) = RefCountable::makeUnique(); + if (auto* next = m_obj4->next()) + return *next; + return *m_obj4; + } + + RefCountable* ensureObj5() { + if (!m_obj5) + const_cast&>(m_obj5) = RefCountable::makeUnique(); + if (m_obj5->next()) + return nullptr; + return m_obj5.get(); + } + private: const std::unique_ptr m_obj1; std::unique_ptr m_obj2; + const std::unique_ptr m_obj3; + const std::unique_ptr m_obj4; + const std::unique_ptr m_obj5; }; void Foo::bar() { m_obj1->method(); m_obj2->method(); // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} + ensureObj3().method(); + badEnsureObj4().method(); + // expected-warning@-1{{Call argument for 'this' parameter is uncounted and unsafe}} + ensureObj5()->method(); } } // namespace call_args_const_unique_ptr diff --git a/clang/test/Analysis/Checkers/WebKit/call-args.cpp b/clang/test/Analysis/Checkers/WebKit/call-args.cpp index 94efddeaf66cd..2146eae9975b9 100644 --- a/clang/test/Analysis/Checkers/WebKit/call-args.cpp +++ b/clang/test/Analysis/Checkers/WebKit/call-args.cpp @@ -117,7 +117,7 @@ namespace null_ptr { namespace ref_counted_lookalike { struct Decoy { - RefCountable* get() { return nullptr; } + RefCountable* get(); }; void foo() { @@ -364,4 +364,15 @@ namespace call_with_explicit_temporary_obj { Ref { *provide() }->method(); RefPtr { provide() }->method(); } + template + void bar() { + Ref(*provide())->method(); + RefPtr(provide())->method(); + } + void baz() { + bar(); + } +} + +namespace call_with_explicit_construct { } diff --git a/clang/test/Analysis/Checkers/WebKit/local-vars-checked-const-member.cpp b/clang/test/Analysis/Checkers/WebKit/local-vars-checked-const-member.cpp index e52d1e735f637..be04cf26be2e8 100644 --- a/clang/test/Analysis/Checkers/WebKit/local-vars-checked-const-member.cpp +++ b/clang/test/Analysis/Checkers/WebKit/local-vars-checked-const-member.cpp @@ -12,9 +12,36 @@ class Foo { Foo(); void bar(); + CheckedObj& ensureObj3() { + if (!m_obj3) + const_cast&>(m_obj3) = new CheckedObj; + return *m_obj3; + } + + CheckedObj& ensureObj4() { + if (!m_obj4) + const_cast&>(m_obj4) = new CheckedObj; + if (auto* next = m_obj4->next()) { + // expected-warning@-1{{Local variable 'next' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} + return *next; + } + return *m_obj4; + } + + CheckedObj* ensureObj5() { + if (!m_obj5) + const_cast&>(m_obj5) = new CheckedObj; + if (m_obj5->next()) + return nullptr; + return m_obj5.get(); + } + private: const CheckedPtr m_obj1; CheckedPtr m_obj2; + const CheckedPtr m_obj3; + const CheckedPtr m_obj4; + const CheckedPtr m_obj5; }; void Foo::bar() { @@ -23,6 +50,12 @@ void Foo::bar() { auto* obj2 = m_obj2.get(); // expected-warning@-1{{Local variable 'obj2' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} obj2->method(); + auto& obj3 = ensureObj3(); + obj3.method(); + auto& obj4 = ensureObj4(); + // expected-warning@-1{{Local variable 'obj4' is unchecked and unsafe [alpha.webkit.UncheckedLocalVarsChecker]}} + obj4.method(); + auto* obj5 = ensureObj5(); } } // namespace local_vars_const_checkedptr_member diff --git a/clang/test/Analysis/Checkers/WebKit/local-vars-counted-const-member.cpp b/clang/test/Analysis/Checkers/WebKit/local-vars-counted-const-member.cpp index 03d16285f88b5..e12c9b900a423 100644 --- a/clang/test/Analysis/Checkers/WebKit/local-vars-counted-const-member.cpp +++ b/clang/test/Analysis/Checkers/WebKit/local-vars-counted-const-member.cpp @@ -12,9 +12,36 @@ class Foo { Foo(); void bar(); + RefCountable& ensureObj3() { + if (!m_obj3) + const_cast&>(m_obj3) = RefCountable::create(); + return *m_obj3; + } + + RefCountable& ensureObj4() { + if (!m_obj4) + const_cast&>(m_obj4) = RefCountable::create(); + if (auto* next = m_obj4->next()) { + // expected-warning@-1{{Local variable 'next' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}} + return *next; + } + return *m_obj4; + } + + RefCountable* ensureObj5() { + if (!m_obj5) + const_cast&>(m_obj5) = RefCountable::create(); + if (m_obj5->next()) + return nullptr; + return m_obj5.get(); + } + private: const RefPtr m_obj1; RefPtr m_obj2; + const RefPtr m_obj3; + const RefPtr m_obj4; + const RefPtr m_obj5; }; void Foo::bar() { @@ -23,6 +50,12 @@ void Foo::bar() { auto* obj2 = m_obj2.get(); // expected-warning@-1{{Local variable 'obj2' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}} obj2->method(); + auto& obj3 = ensureObj3(); + obj3.method(); + auto& obj4 = ensureObj4(); + // expected-warning@-1{{Local variable 'obj4' is uncounted and unsafe [alpha.webkit.UncountedLocalVarsChecker]}} + obj4.method(); + auto* obj5 = ensureObj5(); } } // namespace local_vars_const_refptr_member diff --git a/clang/test/Analysis/Checkers/WebKit/memory-unsafe-cast.cpp b/clang/test/Analysis/Checkers/WebKit/memory-unsafe-cast.cpp new file mode 100644 index 0000000000000..62c945c7a2c24 --- /dev/null +++ b/clang/test/Analysis/Checkers/WebKit/memory-unsafe-cast.cpp @@ -0,0 +1,266 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.MemoryUnsafeCastChecker -verify %s + +class Base { }; +class Derived : public Base { }; + +template +Target& downcast_ref(Source& source){ + [[clang::suppress]] + return static_cast(source); +} + +template +Target* downcast_ptr(Source* source){ + [[clang::suppress]] + return static_cast(source); +} + +void test_pointers(Base *base) { + Derived *derived_static = static_cast(base); + // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}} + Derived *derived_reinterpret = reinterpret_cast(base); + // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}} + Derived *derived_c = (Derived*)base; + // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}} + Derived *derived_d = downcast_ptr(base); // no warning +} + +void test_non_pointers(Derived derived) { + Base base_static = static_cast(derived); // no warning +} + +void test_refs(Base &base) { + Derived &derived_static = static_cast(base); + // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}} + Derived &derived_reinterpret = reinterpret_cast(base); + // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}} + Derived &derived_c = (Derived&)base; + // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}} + Derived &derived_d = downcast_ref(base); // no warning +} + +class BaseVirtual { + virtual void virtual_base_function(); +}; + +class DerivedVirtual : public BaseVirtual { + void virtual_base_function() override { } +}; + +void test_dynamic_casts(BaseVirtual *base_ptr, BaseVirtual &base_ref) { + DerivedVirtual *derived_dynamic_ptr = dynamic_cast(base_ptr); + // expected-warning@-1{{Unsafe cast from base type 'BaseVirtual' to derived type 'DerivedVirtual'}} + DerivedVirtual &derived_dynamic_ref = dynamic_cast(base_ref); + // expected-warning@-1{{Unsafe cast from base type 'BaseVirtual' to derived type 'DerivedVirtual'}} +} + +struct BaseStruct { }; +struct DerivedStruct : BaseStruct { }; + +void test_struct_pointers(struct BaseStruct *base_struct) { + struct DerivedStruct *derived_static = static_cast(base_struct); + // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}} + struct DerivedStruct *derived_reinterpret = reinterpret_cast(base_struct); + // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}} + struct DerivedStruct *derived_c = (struct DerivedStruct*)base_struct; + // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}} +} + +typedef struct BaseStruct BStruct; +typedef struct DerivedStruct DStruct; + +void test_struct_refs(BStruct &base_struct) { + DStruct &derived_static = static_cast(base_struct); + // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}} + DStruct &derived_reinterpret = reinterpret_cast(base_struct); + // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}} + DStruct &derived_c = (DStruct&)base_struct; + // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}} +} + +int counter = 0; +void test_recursive(BStruct &base_struct) { + if (counter == 5) + return; + counter++; + DStruct &derived_static = static_cast(base_struct); + // expected-warning@-1{{Unsafe cast from base type 'BaseStruct' to derived type 'DerivedStruct'}} +} + +template +class BaseTemplate { }; + +template +class DerivedTemplate : public BaseTemplate { }; + +void test_templates(BaseTemplate *base, BaseTemplate &base_ref) { + DerivedTemplate *derived_static = static_cast*>(base); + // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}} + DerivedTemplate *derived_reinterpret = reinterpret_cast*>(base); + // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}} + DerivedTemplate *derived_c = (DerivedTemplate*)base; + // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}} + DerivedTemplate &derived_static_ref = static_cast&>(base_ref); + // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}} + DerivedTemplate &derived_reinterpret_ref = reinterpret_cast&>(base_ref); + // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}} + DerivedTemplate &derived_c_ref = (DerivedTemplate&)base_ref; + // expected-warning@-1{{Unsafe cast from base type 'BaseTemplate' to derived type 'DerivedTemplate'}} +} + +#define CAST_MACRO_STATIC(X,Y) (static_cast(X)) +#define CAST_MACRO_REINTERPRET(X,Y) (reinterpret_cast(X)) +#define CAST_MACRO_C(X,Y) ((Y)X) + +void test_macro_static(Base *base, Derived *derived, Base &base_ref) { + Derived *derived_static = CAST_MACRO_STATIC(base, Derived*); + // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}} + Derived &derived_static_ref = CAST_MACRO_STATIC(base_ref, Derived&); + // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}} + Base *base_static_same = CAST_MACRO_STATIC(base, Base*); // no warning + Base *base_static_upcast = CAST_MACRO_STATIC(derived, Base*); // no warning +} + +void test_macro_reinterpret(Base *base, Derived *derived, Base &base_ref) { + Derived *derived_reinterpret = CAST_MACRO_REINTERPRET(base, Derived*); + // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}} + Derived &derived_reinterpret_ref = CAST_MACRO_REINTERPRET(base_ref, Derived&); + // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}} + Base *base_reinterpret_same = CAST_MACRO_REINTERPRET(base, Base*); // no warning + Base *base_reinterpret_upcast = CAST_MACRO_REINTERPRET(derived, Base*); // no warning +} + +void test_macro_c(Base *base, Derived *derived, Base &base_ref) { + Derived *derived_c = CAST_MACRO_C(base, Derived*); + // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}} + Derived &derived_c_ref = CAST_MACRO_C(base_ref, Derived&); + // expected-warning@-1{{Unsafe cast from base type 'Base' to derived type 'Derived'}} + Base *base_c_same = CAST_MACRO_C(base, Base*); // no warning + Base *base_c_upcast = CAST_MACRO_C(derived, Base*); // no warning +} + +struct BaseStructCpp { + int t; + void increment() { t++; } +}; +struct DerivedStructCpp : BaseStructCpp { + void increment_t() {increment();} +}; + +void test_struct_cpp_pointers(struct BaseStructCpp *base_struct) { + struct DerivedStructCpp *derived_static = static_cast(base_struct); + // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}} + struct DerivedStructCpp *derived_reinterpret = reinterpret_cast(base_struct); + // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}} + struct DerivedStructCpp *derived_c = (struct DerivedStructCpp*)base_struct; + // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}} +} + +typedef struct BaseStructCpp BStructCpp; +typedef struct DerivedStructCpp DStructCpp; + +void test_struct_cpp_refs(BStructCpp &base_struct, DStructCpp &derived_struct) { + DStructCpp &derived_static = static_cast(base_struct); + // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}} + DStructCpp &derived_reinterpret = reinterpret_cast(base_struct); + // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}} + DStructCpp &derived_c = (DStructCpp&)base_struct; + // expected-warning@-1{{Unsafe cast from base type 'BaseStructCpp' to derived type 'DerivedStructCpp'}} + BStructCpp &base = (BStructCpp&)derived_struct; // no warning + BStructCpp &base_static = static_cast(derived_struct); // no warning + BStructCpp &base_reinterpret = reinterpret_cast(derived_struct); // no warning +} + +struct stack_st { }; + +#define STACK_OF(type) struct stack_st_##type + +void test_stack(stack_st *base) { + STACK_OF(void) *derived = (STACK_OF(void)*)base; + // expected-warning@-1{{Unsafe cast from type 'stack_st' to an unrelated type 'stack_st_void'}} +} + +class Parent { }; +class Child1 : public Parent { }; +class Child2 : public Parent { }; + +void test_common_parent(Child1 *c1, Child2 *c2) { + Child2 *c2_cstyle = (Child2 *)c1; + // expected-warning@-1{{Unsafe cast from type 'Child1' to an unrelated type 'Child2'}} + Child2 *c2_reinterpret = reinterpret_cast(c1); + // expected-warning@-1{{Unsafe cast from type 'Child1' to an unrelated type 'Child2'}} +} + +class Type1 { }; +class Type2 { }; + +void test_unrelated_ref(Type1 &t1, Type2 &t2) { + Type2 &t2_cstyle = (Type2 &)t1; + // expected-warning@-1{{Unsafe cast from type 'Type1' to an unrelated type 'Type2'}} + Type2 &t2_reinterpret = reinterpret_cast(t1); + // expected-warning@-1{{Unsafe cast from type 'Type1' to an unrelated type 'Type2'}} + Type2 &t2_same = reinterpret_cast(t2); // no warning +} + + +class VirtualClass1 { + virtual void virtual_base_function(); +}; + +class VirtualClass2 { + void virtual_base_function(); +}; + +void test_unrelated_virtual(VirtualClass1 &v1) { + VirtualClass2 &v2 = dynamic_cast(v1); + // expected-warning@-1{{Unsafe cast from type 'VirtualClass1' to an unrelated type 'VirtualClass2'}} +} + +struct StructA { }; +struct StructB { }; + +typedef struct StructA StA; +typedef struct StructB StB; + +void test_struct_unrelated_refs(StA &a, StB &b) { + StB &b_reinterpret = reinterpret_cast(a); + // expected-warning@-1{{Unsafe cast from type 'StructA' to an unrelated type 'StructB'}} + StB &b_c = (StB&)a; + // expected-warning@-1{{Unsafe cast from type 'StructA' to an unrelated type 'StructB'}} + StA &a_local = (StA&)b; + // expected-warning@-1{{Unsafe cast from type 'StructB' to an unrelated type 'StructA'}} + StA &a_reinterpret = reinterpret_cast(b); + // expected-warning@-1{{Unsafe cast from type 'StructB' to an unrelated type 'StructA'}} + StA &a_same = (StA&)a; // no warning +} + +template +class DeferrableRefCounted { +public: + void deref() const { + auto this_to_T = static_cast(this); // no warning + } +}; + +class SomeArrayClass : public DeferrableRefCounted { }; + +void test_this_to_template(SomeArrayClass *ptr) { + ptr->deref(); +}; + +template +class CanMakeWeakPtrBase { +public: + void initializeWeakPtrFactory() const { + auto &this_to_T = static_cast(*this); + } +}; + +template +using CanMakeWeakPtr = CanMakeWeakPtrBase; + +class EventLoop : public CanMakeWeakPtr { }; + +void test_this_to_template_ref(EventLoop *ptr) { + ptr->initializeWeakPtrFactory(); +}; diff --git a/clang/test/Analysis/Checkers/WebKit/memory-unsafe-cast.mm b/clang/test/Analysis/Checkers/WebKit/memory-unsafe-cast.mm new file mode 100644 index 0000000000000..f9046d7981784 --- /dev/null +++ b/clang/test/Analysis/Checkers/WebKit/memory-unsafe-cast.mm @@ -0,0 +1,64 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.webkit.MemoryUnsafeCastChecker -verify %s + +@protocol NSObject ++alloc; +-init; +@end + +@interface NSObject {} +@end + +@interface BaseClass : NSObject +@end + +@interface DerivedClass : BaseClass +-(void)testCasts:(BaseClass*)base; +@end + +@implementation DerivedClass +-(void)testCasts:(BaseClass*)base { + DerivedClass *derived = (DerivedClass*)base; + // expected-warning@-1{{Unsafe cast from base type 'BaseClass' to derived type 'DerivedClass'}} + DerivedClass *derived_static = static_cast(base); + // expected-warning@-1{{Unsafe cast from base type 'BaseClass' to derived type 'DerivedClass'}} + DerivedClass *derived_reinterpret = reinterpret_cast(base); + // expected-warning@-1{{Unsafe cast from base type 'BaseClass' to derived type 'DerivedClass'}} + base = (BaseClass*)derived; // no warning + base = (BaseClass*)base; // no warning +} +@end + +template +class WrappedObject +{ +public: + T get() const { return mMetalObject; } + T mMetalObject = nullptr; +}; + +@protocol MTLCommandEncoder +@end +@protocol MTLRenderCommandEncoder +@end +class CommandEncoder : public WrappedObject> { }; + +class RenderCommandEncoder final : public CommandEncoder +{ +private: + id get() + { + return static_cast>(CommandEncoder::get()); + } +}; + +@interface Class1 +@end + +@interface Class2 +@end + +void testUnrelated(Class1 *c1) { + Class2 *c2 = (Class2*)c1; + // expected-warning@-1{{Unsafe cast from type 'Class1' to an unrelated type 'Class2'}} + Class1 *c1_same = reinterpret_cast(c1); // no warning +} diff --git a/clang/test/Analysis/Checkers/WebKit/mock-types.h b/clang/test/Analysis/Checkers/WebKit/mock-types.h index fb1ee51c7ec1d..f3bd20f8bcf60 100644 --- a/clang/test/Analysis/Checkers/WebKit/mock-types.h +++ b/clang/test/Analysis/Checkers/WebKit/mock-types.h @@ -1,6 +1,34 @@ #ifndef mock_types_1103988513531 #define mock_types_1103988513531 +namespace std { + +template +class unique_ptr { +private: + T *t; + +public: + unique_ptr() : t(nullptr) { } + unique_ptr(T *t) : t(t) { } + ~unique_ptr() { + if (t) + delete t; + } + template unique_ptr(unique_ptr&& u) + : t(u.t) + { + u.t = nullptr; + } + T *get() const { return t; } + T *operator->() const { return t; } + T &operator*() const { return *t; } + unique_ptr &operator=(T *) { return *this; } + explicit operator bool() const { return !!t; } +}; + +}; + template struct RawPtrTraits { using StorageType = T*; @@ -103,7 +131,7 @@ template struct RefPtr { } T *get() const { return t; } T *operator->() const { return t; } - T &operator*() { return *t; } + T &operator*() const { return *t; } RefPtr &operator=(T *t) { RefPtr o(t); swap(o); @@ -130,6 +158,7 @@ template bool operator!=(const RefPtr &, T &) { return false; } struct RefCountable { static Ref create(); + static std::unique_ptr makeUnique(); void ref() {} void deref() {} void method(); @@ -176,7 +205,7 @@ template struct CheckedPtr { } T *get() const { return t; } T *operator->() const { return t; } - T &operator*() { return *t; } + T &operator*() const { return *t; } CheckedPtr &operator=(T *) { return *this; } operator bool() const { return t; } }; @@ -187,6 +216,7 @@ class CheckedObj { void decrementCheckedPtrCount(); void method(); int trivial() { return 123; } + CheckedObj* next(); }; class RefCountableAndCheckable { @@ -220,31 +250,4 @@ class UniqueRef { UniqueRef &operator=(T &) { return *this; } }; -namespace std { - -template -class unique_ptr { -private: - T *t; - -public: - unique_ptr() : t(nullptr) { } - unique_ptr(T *t) : t(t) { } - ~unique_ptr() { - if (t) - delete t; - } - template unique_ptr(unique_ptr&& u) - : t(u.t) - { - u.t = nullptr; - } - T *get() const { return t; } - T *operator->() const { return t; } - T &operator*() { return *t; } - unique_ptr &operator=(T *) { return *this; } -}; - -}; - #endif diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp index 65eee9d49106d..daff32e9940c8 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-lambda-captures.cpp @@ -1,16 +1,72 @@ // RUN: %clang_analyze_cc1 -analyzer-checker=webkit.UncountedLambdaCapturesChecker -verify %s -struct A { - static void b(); +#include "mock-types.h" + +namespace WTF { + +namespace Detail { + +template +class CallableWrapperBase { +public: + virtual ~CallableWrapperBase() { } + virtual Out call(In...) = 0; +}; + +template class CallableWrapper; + +template +class CallableWrapper : public CallableWrapperBase { +public: + explicit CallableWrapper(CallableType& callable) + : m_callable(callable) { } + Out call(In... in) final { return m_callable(in...); } + +private: + CallableType m_callable; +}; + +} // namespace Detail + +template class Function; + +template Function adopt(Detail::CallableWrapperBase*); + +template +class Function { +public: + using Impl = Detail::CallableWrapperBase; + + Function() = default; + + template + Function(FunctionType f) + : m_callableWrapper(new Detail::CallableWrapper(f)) { } + + Out operator()(In... in) const { return m_callableWrapper->call(in...); } + explicit operator bool() const { return !!m_callableWrapper; } + +private: + enum AdoptTag { Adopt }; + Function(Impl* impl, AdoptTag) + : m_callableWrapper(impl) + { + } + + friend Function adopt(Impl*); + + std::unique_ptr m_callableWrapper; }; -struct RefCountable { - void ref() {} - void deref() {} - void method(); - void constMethod() const; - int trivial() { return 123; } - RefCountable* next(); +template Function adopt(Detail::CallableWrapperBase* impl) +{ + return Function(impl, Function::Adopt); +} + +} // namespace WTF + +struct A { + static void b(); }; RefCountable* make_obj(); @@ -185,3 +241,21 @@ void lambda_with_args(RefCountable* obj) { }; trivial_lambda(1); } + +void callFunctionOpaque(WTF::Function&&); +void callFunction(WTF::Function&& function) { + someFunction(); + function(); +} + +void lambda_converted_to_function(RefCountable* obj) +{ + callFunction([&]() { + obj->method(); + // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to ref-counted type or CheckedPtr-capable type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + }); + callFunctionOpaque([&]() { + obj->method(); + // expected-warning@-1{{Implicitly captured raw-pointer 'obj' to ref-counted type or CheckedPtr-capable type is unsafe [webkit.UncountedLambdaCapturesChecker]}} + }); +} diff --git a/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp b/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp index d7fb689557a6f..52854cd10f68c 100644 --- a/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp +++ b/clang/test/Analysis/Checkers/WebKit/uncounted-local-vars.cpp @@ -456,3 +456,12 @@ int TreeNode::recursiveWeight() { } } // namespace local_var_in_recursive_function + +namespace local_var_for_singleton { + RefCountable *singleton(); + RefCountable *otherSingleton(); + void foo() { + RefCountable* bar = singleton(); + RefCountable* baz = otherSingleton(); + } +} \ No newline at end of file diff --git a/clang/test/Analysis/analyzer-config.c b/clang/test/Analysis/analyzer-config.c index 47594e8317bc7..8ce6184144d4b 100644 --- a/clang/test/Analysis/analyzer-config.c +++ b/clang/test/Analysis/analyzer-config.c @@ -40,9 +40,9 @@ // CHECK-NEXT: cplusplus.Move:WarnOn = KnownsAndLocals // CHECK-NEXT: cplusplus.SmartPtrModeling:ModelSmartPtrDereference = false // CHECK-NEXT: crosscheck-with-z3 = false -// CHECK-NEXT: crosscheck-with-z3-eqclass-timeout-threshold = 700 -// CHECK-NEXT: crosscheck-with-z3-rlimit-threshold = 400000 -// CHECK-NEXT: crosscheck-with-z3-timeout-threshold = 300 +// CHECK-NEXT: crosscheck-with-z3-eqclass-timeout-threshold = 0 +// CHECK-NEXT: crosscheck-with-z3-rlimit-threshold = 0 +// CHECK-NEXT: crosscheck-with-z3-timeout-threshold = 15000 // CHECK-NEXT: ctu-dir = "" // CHECK-NEXT: ctu-import-cpp-threshold = 8 // CHECK-NEXT: ctu-import-threshold = 24 diff --git a/clang/test/CIR/global-var-simple.cpp b/clang/test/CIR/global-var-simple.cpp new file mode 100644 index 0000000000000..5230ff53f87d7 --- /dev/null +++ b/clang/test/CIR/global-var-simple.cpp @@ -0,0 +1,59 @@ +// Global variables of intergal types +// RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o - | FileCheck %s + +char c; +// CHECK: cir.global @c : !cir.int + +signed char sc; +// CHECK: cir.global @sc : !cir.int + +unsigned char uc; +// CHECK: cir.global @uc : !cir.int + +short ss; +// CHECK: cir.global @ss : !cir.int + +unsigned short us; +// CHECK: cir.global @us : !cir.int + +int si; +// CHECK: cir.global @si : !cir.int + +unsigned ui; +// CHECK: cir.global @ui : !cir.int + +long sl; +// CHECK: cir.global @sl : !cir.int + +unsigned long ul; +// CHECK: cir.global @ul : !cir.int + +long long sll; +// CHECK: cir.global @sll : !cir.int + +unsigned long long ull; +// CHECK: cir.global @ull : !cir.int + +__int128 s128; +// CHECK: cir.global @s128 : !cir.int + +unsigned __int128 u128; +// CHECK: cir.global @u128 : !cir.int + +wchar_t wc; +// CHECK: cir.global @wc : !cir.int + +char8_t c8; +// CHECK: cir.global @c8 : !cir.int + +char16_t c16; +// CHECK: cir.global @c16 : !cir.int + +char32_t c32; +// CHECK: cir.global @c32 : !cir.int + +_BitInt(20) sb20; +// CHECK: cir.global @sb20 : !cir.int + +unsigned _BitInt(48) ub48; +// CHECK: cir.global @ub48 : !cir.int diff --git a/clang/test/CXX/conv/conv.mem/p4.cpp b/clang/test/CXX/conv/conv.mem/p4.cpp index d052b7927b32d..552c908a6610b 100644 --- a/clang/test/CXX/conv/conv.mem/p4.cpp +++ b/clang/test/CXX/conv/conv.mem/p4.cpp @@ -19,8 +19,8 @@ namespace test0 { namespace test1 { struct Derived : private Base {}; // expected-note 2 {{declared private here}} void test() { - int (Derived::*d) = data_ptr; // expected-error {{cannot cast private base class 'Base' to 'test1::Derived'}} - int (Derived::*m)() = method_ptr; // expected-error {{cannot cast private base class 'Base' to 'test1::Derived'}} + int (Derived::*d) = data_ptr; // expected-error {{cannot cast private base class 'Base' to 'Derived'}} + int (Derived::*m)() = method_ptr; // expected-error {{cannot cast private base class 'Base' to 'Derived'}} } }; @@ -30,8 +30,8 @@ namespace test2 { struct B : Base {}; struct Derived : A, B {}; void test() { - int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test2::Derived':}} - int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test2::Derived':}} + int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'Derived':}} + int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'Derived':}} } } @@ -39,8 +39,8 @@ namespace test2 { namespace test3 { struct Derived : virtual Base {}; void test() { - int (Derived::*d) = data_ptr; // expected-error {{conversion from pointer to member of class 'Base' to pointer to member of class 'test3::Derived' via virtual base 'Base' is not allowed}} - int (Derived::*m)() = method_ptr; // expected-error {{conversion from pointer to member of class 'Base' to pointer to member of class 'test3::Derived' via virtual base 'Base' is not allowed}} + int (Derived::*d) = data_ptr; // expected-error {{conversion from pointer to member of class 'Base' to pointer to member of class 'Derived' via virtual base 'Base' is not allowed}} + int (Derived::*m)() = method_ptr; // expected-error {{conversion from pointer to member of class 'Base' to pointer to member of class 'Derived' via virtual base 'Base' is not allowed}} } } @@ -49,8 +49,8 @@ namespace test4 { struct A : Base {}; struct Derived : Base, virtual A {}; // expected-warning {{direct base 'Base' is inaccessible due to ambiguity:\n struct test4::Derived -> Base\n struct test4::Derived -> A -> Base}} void test() { - int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test4::Derived':}} - int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'test4::Derived':}} + int (Derived::*d) = data_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'Derived':}} + int (Derived::*m)() = method_ptr; // expected-error {{ambiguous conversion from pointer to member of base class 'Base' to pointer to member of derived class 'Derived':}} } } diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp index dbb6e60d9b93d..a633c108bc22c 100644 --- a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp +++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp @@ -57,9 +57,11 @@ template void b(T[] ...); template -void c(T ... []); // expected-error {{expected expression}} \ - // expected-error {{'T' does not refer to the name of a parameter pack}} \ - // expected-warning {{pack indexing is a C++2c extension}} +void c(T ... []); // expected-error {{type 'T[]' of function parameter pack does not contain any unexpanded parameter packs}} + +// A function that takes pointers to each type T as arguments, after any decay. +template +void g(T...[]); template void d(T ... x[]); // expected-error{{type 'T[]' of function parameter pack does not contain any unexpanded parameter packs}} diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp index fe3e0cfc1d421..993b6f2923859 100644 --- a/clang/test/CXX/drs/cwg0xx.cpp +++ b/clang/test/CXX/drs/cwg0xx.cpp @@ -858,7 +858,7 @@ namespace cwg54 { // cwg54: 2.8 // expected-error@-1 {{cannot cast 'struct B' to its private base class 'A'}} // expected-note@#cwg54-B {{declared private here}} int A::*smab = static_cast(&B::b); - // expected-error@-1 {{cannot cast 'cwg54::B' to its private base class 'cwg54::A'}} + // expected-error@-1 {{cannot cast 'cwg54::B' to its private base class 'A'}} // expected-note@#cwg54-B {{declared private here}} B &sba = static_cast(a); // expected-error@-1 {{cannot cast private base class 'cwg54::A' to 'cwg54::B'}} @@ -867,19 +867,19 @@ namespace cwg54 { // cwg54: 2.8 // expected-error@-1 {{cannot cast private base class 'cwg54::A' to 'cwg54::B'}} // expected-note@#cwg54-B {{declared private here}} int B::*smba = static_cast(&A::a); - // expected-error@-1 {{cannot cast private base class 'cwg54::A' to 'cwg54::B'}} + // expected-error@-1 {{cannot cast private base class 'cwg54::A' to 'B'}} // expected-note@#cwg54-B {{declared private here}} V &svb = static_cast(b); V *spvb = static_cast(&b); int V::*smvb = static_cast(&B::b); - // expected-error@-1 {{conversion from pointer to member of class 'cwg54::B' to pointer to member of class 'cwg54::V' via virtual base 'cwg54::V' is not allowed}} + // expected-error@-1 {{conversion from pointer to member of class 'cwg54::B' to pointer to member of class 'V' via virtual base 'cwg54::V' is not allowed}} B &sbv = static_cast(v); // expected-error@-1 {{cannot cast 'struct V' to 'B &' via virtual base 'cwg54::V'}} B *spbv = static_cast(&v); // expected-error@-1 {{cannot cast 'cwg54::V *' to 'B *' via virtual base 'cwg54::V'}} int B::*smbv = static_cast(&V::v); - // expected-error@-1 {{conversion from pointer to member of class 'cwg54::V' to pointer to member of class 'cwg54::B' via virtual base 'cwg54::V' is not allowed}} + // expected-error@-1 {{conversion from pointer to member of class 'cwg54::V' to pointer to member of class 'B' via virtual base 'cwg54::V' is not allowed}} A &cab = (A&)(b); A *cpab = (A*)(&b); @@ -891,13 +891,13 @@ namespace cwg54 { // cwg54: 2.8 V &cvb = (V&)(b); V *cpvb = (V*)(&b); int V::*cmvb = (int V::*)(&B::b); - // expected-error@-1 {{conversion from pointer to member of class 'cwg54::B' to pointer to member of class 'cwg54::V' via virtual base 'cwg54::V' is not allowed}} + // expected-error@-1 {{conversion from pointer to member of class 'cwg54::B' to pointer to member of class 'V' via virtual base 'cwg54::V' is not allowed}} B &cbv = (B&)(v); // expected-error@-1 {{cannot cast 'struct V' to 'B &' via virtual base 'cwg54::V'}} B *cpbv = (B*)(&v); // expected-error@-1 {{cannot cast 'cwg54::V *' to 'B *' via virtual base 'cwg54::V'}} int B::*cmbv = (int B::*)(&V::v); - // expected-error@-1 {{conversion from pointer to member of class 'cwg54::V' to pointer to member of class 'cwg54::B' via virtual base 'cwg54::V' is not allowed}} + // expected-error@-1 {{conversion from pointer to member of class 'cwg54::V' to pointer to member of class 'B' via virtual base 'cwg54::V' is not allowed}} } namespace cwg55 { // cwg55: yes diff --git a/clang/test/CXX/drs/cwg13xx.cpp b/clang/test/CXX/drs/cwg13xx.cpp index 416de7c536b1a..980fcb4eb18ac 100644 --- a/clang/test/CXX/drs/cwg13xx.cpp +++ b/clang/test/CXX/drs/cwg13xx.cpp @@ -204,7 +204,7 @@ namespace cwg1330 { // cwg1330: 4 c++11 // since-cxx17-note@-2 {{use 'noexcept(false)' instead}} void (A::*af2)() throw() = &A::f; // cxx98-14-error@-1 {{target exception specification is not superset of source}} - // since-cxx17-error@-2 {{cannot initialize a variable of type 'void (cwg1330::A::*)() throw()' with an rvalue of type 'void (cwg1330::A::*)() throw(T)': different exception specifications}} + // since-cxx17-error@-2 {{cannot initialize a variable of type 'void (A::*)() throw()' with an rvalue of type 'void (cwg1330::A::*)() throw(T)': different exception specifications}} #if __cplusplus >= 201103L static_assert(noexcept(A().g()), ""); diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp index 10c8d86ed16a0..26b0f975effa1 100644 --- a/clang/test/CXX/drs/cwg3xx.cpp +++ b/clang/test/CXX/drs/cwg3xx.cpp @@ -537,9 +537,9 @@ namespace cwg330 { // cwg330: 7 void f(A *a) { (void) reinterpret_cast(a); (void) reinterpret_cast(a); - // expected-error@-1 {{ISO C++ does not allow reinterpret_cast from 'A *' (aka 'const volatile int (*)[1][2][3]') to 'B2 *' (aka 'int *const cwg330::swift_17882::X::***') because it casts away qualifiers, even though the source and destination types are unrelated}} + // expected-error@-1 {{ISO C++ does not allow reinterpret_cast from 'A *' (aka 'const volatile int (*)[1][2][3]') to 'B2 *' (aka 'int *const X::***') because it casts away qualifiers, even though the source and destination types are unrelated}} (void) reinterpret_cast(a); - // expected-error@-1 {{ISO C++ does not allow reinterpret_cast from 'A *' (aka 'const volatile int (*)[1][2][3]') to 'B3 *' (aka 'int *cwg330::swift_17882::X::*volatile **') because it casts away qualifiers, even though the source and destination types are unrelated}} + // expected-error@-1 {{ISO C++ does not allow reinterpret_cast from 'A *' (aka 'const volatile int (*)[1][2][3]') to 'B3 *' (aka 'int *X::*volatile **') because it casts away qualifiers, even though the source and destination types are unrelated}} (void) reinterpret_cast(a); } } @@ -971,9 +971,9 @@ namespace cwg354 { // cwg354: yes c++11 ptr<(int S::*)0> p3; // #cwg354-p3 // cxx98-error@#cwg354-p3 {{non-type template argument does not refer to any declaration}} // cxx98-note@#cwg354-ptr {{template parameter is declared here}} - // cxx11-14-error@#cwg354-p3 {{null non-type template argument of type 'int cwg354::S::*' does not match template parameter of type 'int *'}} + // cxx11-14-error@#cwg354-p3 {{null non-type template argument of type 'int S::*' does not match template parameter of type 'int *'}} // cxx11-14-note@#cwg354-ptr {{template parameter is declared here}} - // since-cxx17-error@#cwg354-p3 {{value of type 'int cwg354::S::*' is not implicitly convertible to 'int *'}} + // since-cxx17-error@#cwg354-p3 {{value of type 'int S::*' is not implicitly convertible to 'int *'}} template int both(); // #cwg354-both-int-ptr template int both(); // #cwg354-both-int @@ -985,25 +985,25 @@ namespace cwg354 { // cwg354: yes c++11 template struct ptr_mem {}; // #cwg354-ptr_mem ptr_mem<0> m0; // #cwg354-m0 - // cxx98-error@#cwg354-m0 {{non-type template argument of type 'int' cannot be converted to a value of type 'int cwg354::S::*'}} + // cxx98-error@#cwg354-m0 {{non-type template argument of type 'int' cannot be converted to a value of type 'int S::*'}} // cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}} - // cxx11-14-error@#cwg354-m0 {{null non-type template argument must be cast to template parameter type 'int cwg354::S::*'}} + // cxx11-14-error@#cwg354-m0 {{null non-type template argument must be cast to template parameter type 'int S::*'}} // cxx11-14-note@#cwg354-ptr_mem {{template parameter is declared here}} - // since-cxx17-error@#cwg354-m0 {{conversion from 'int' to 'int cwg354::S::*' is not allowed in a converted constant expression}} + // since-cxx17-error@#cwg354-m0 {{conversion from 'int' to 'int S::*' is not allowed in a converted constant expression}} ptr_mem<(int S::*)0> m1; // cxx98-error@-1 {{non-type template argument is not a pointer to member constant}} ptr_mem<(float S::*)0> m2; // #cwg354-m2 - // cxx98-error@#cwg354-m2 {{non-type template argument of type 'float cwg354::S::*' cannot be converted to a value of type 'int cwg354::S::*'}} + // cxx98-error@#cwg354-m2 {{non-type template argument of type 'float S::*' cannot be converted to a value of type 'int S::*'}} // cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}} - // cxx11-14-error@#cwg354-m2 {{null non-type template argument of type 'float cwg354::S::*' does not match template parameter of type 'int cwg354::S::*'}} + // cxx11-14-error@#cwg354-m2 {{null non-type template argument of type 'float S::*' does not match template parameter of type 'int S::*'}} // cxx11-14-note@#cwg354-ptr_mem {{template parameter is declared here}} - // since-cxx17-error@#cwg354-m2 {{value of type 'float cwg354::S::*' is not implicitly convertible to 'int cwg354::S::*'}} + // since-cxx17-error@#cwg354-m2 {{value of type 'float S::*' is not implicitly convertible to 'int S::*'}} ptr_mem<(int *)0> m3; // #cwg354-m3 - // cxx98-error@#cwg354-m3 {{non-type template argument of type 'int *' cannot be converted to a value of type 'int cwg354::S::*'}} + // cxx98-error@#cwg354-m3 {{non-type template argument of type 'int *' cannot be converted to a value of type 'int S::*'}} // cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}} - // cxx11-14-error@#cwg354-m3 {{null non-type template argument of type 'int *' does not match template parameter of type 'int cwg354::S::*'}} + // cxx11-14-error@#cwg354-m3 {{null non-type template argument of type 'int *' does not match template parameter of type 'int S::*'}} // cxx11-14-note@#cwg354-ptr_mem {{template parameter is declared here}} - // since-cxx17-error@#cwg354-m3 {{value of type 'int *' is not implicitly convertible to 'int cwg354::S::*'}} + // since-cxx17-error@#cwg354-m3 {{value of type 'int *' is not implicitly convertible to 'int S::*'}} } struct cwg355_S; // cwg355: yes @@ -1701,7 +1701,7 @@ namespace cwg395 { // cwg395: 3.0 } } null1; int (S::*p)() = null1; - // expected-error@-1 {{no viable conversion from 'struct null1_t' to 'int (cwg395::S::*)()'}} + // expected-error@-1 {{no viable conversion from 'struct null1_t' to 'int (S::*)()'}} // expected-note@#cwg395-conv-func {{candidate template ignored: couldn't infer template argument 'T'}} template using id = T; diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp index 98ff7553d989b..825065840f118 100644 --- a/clang/test/CXX/drs/cwg4xx.cpp +++ b/clang/test/CXX/drs/cwg4xx.cpp @@ -1172,11 +1172,11 @@ namespace cwg480 { // cwg480: yes int A::*a = &A::n; int D::*b = a; - // expected-error@-1 {{conversion from pointer to member of class 'cwg480::A' to pointer to member of class 'cwg480::D' via virtual base 'cwg480::B' is not allowed}} + // expected-error@-1 {{conversion from pointer to member of class 'A' to pointer to member of class 'D' via virtual base 'cwg480::B' is not allowed}} extern int D::*c; int A::*d = static_cast(c); - // expected-error@-1 {{conversion from pointer to member of class 'cwg480::D' to pointer to member of class 'cwg480::A' via virtual base 'cwg480::B' is not allowed}} + // expected-error@-1 {{conversion from pointer to member of class 'cwg480::D' to pointer to member of class 'A' via virtual base 'cwg480::B' is not allowed}} D *e; A *f = e; diff --git a/clang/test/CXX/drs/cwg5xx.cpp b/clang/test/CXX/drs/cwg5xx.cpp index 91a76fd2adbb6..9219a4c857b12 100644 --- a/clang/test/CXX/drs/cwg5xx.cpp +++ b/clang/test/CXX/drs/cwg5xx.cpp @@ -184,7 +184,7 @@ namespace cwg522 { // cwg522: yes b2(am); b2a(am); // expected-error@-1 {{no matching function for call to 'b2a'}} - // expected-note@#cwg522-b2a {{candidate template ignored: deduced type 'volatile int *cwg522::S::*const *' of 1st parameter does not match adjusted type 'int *cwg522::S::**' of argument}} + // expected-note@#cwg522-b2a {{candidate template ignored: deduced type 'volatile int *S::*const *' of 1st parameter does not match adjusted type 'int *S::**' of argument}} b3(d); b3(cd); } @@ -1209,6 +1209,11 @@ namespace cwg591 { // cwg591: 20 }; }; + template struct M { + class P; + int M; + }; + template struct A::B::C : A { M m; }; @@ -1224,6 +1229,10 @@ namespace cwg591 { // cwg591: 20 M m; }; + template class M::P : M { + int foo() { (void) M; } + }; + template struct A::B::D : A { M m; // expected-error@-1 {{field has incomplete type 'M' (aka 'void'}} diff --git a/clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp b/clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp index 170ca0a3f1c6b..e49f396143ad6 100644 --- a/clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp +++ b/clang/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp @@ -6,7 +6,7 @@ namespace test0 { template void g(T); void test() { - foo(&g); // expected-error-re {{cannot form member pointer of type 'void (test0::A::*)(int){{( __attribute__\(\(thiscall\)\))?}}' without '&' and class name}} + foo(&g); // expected-error-re {{cannot form member pointer of type 'void (A::*)(int){{( __attribute__\(\(thiscall\)\))?}}' without '&' and class name}} } }; } diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp index 5341290a1446e..034ad49d0715c 100644 --- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp +++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp @@ -223,7 +223,7 @@ namespace pointer_to_member_function { template struct X0 {}; // expected-note 0-1{{template parameter is declared here}} X0<&Y::f> x0a; X0<&Y::g> x0b; - X0<&Y::h> x0c; // expected-error-re{{type 'float (pointer_to_member_function::Y::*)(float){{( __attribute__\(\(thiscall\)\))?}}' {{.*}} convert{{.*}} 'int (pointer_to_member_function::Y::*)(int){{( __attribute__\(\(thiscall\)\))?}}'}} + X0<&Y::h> x0c; // expected-error-re{{type 'float (pointer_to_member_function::Y::*)(float){{( __attribute__\(\(thiscall\)\))?}}' {{.*}} convert{{.*}} 'int (Y::*)(int){{( __attribute__\(\(thiscall\)\))?}}'}} } // -- For a non-type template-parameter of type pointer to data member, @@ -238,9 +238,9 @@ namespace pointer_to_member_data { X0<&Y::y> x0a; X0<&Y::x> x0b; #if __cplusplus <= 201402L - // expected-error@-2 {{non-type template argument of type 'int pointer_to_member_data::X::*' cannot be converted to a value of type 'int pointer_to_member_data::Y::*'}} + // expected-error@-2 {{non-type template argument of type 'int pointer_to_member_data::X::*' cannot be converted to a value of type 'int Y::*'}} #else - // expected-error@-4 {{conversion from 'int pointer_to_member_data::X::*' to 'int pointer_to_member_data::Y::*' is not allowed in a converted constant expression}} + // expected-error@-4 {{conversion from 'int pointer_to_member_data::X::*' to 'int Y::*' is not allowed in a converted constant expression}} #endif // Test qualification conversions diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp index 87c22a0d7e944..50dedb1a158d3 100644 --- a/clang/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp +++ b/clang/test/CXX/temp/temp.decls/temp.variadic/sizeofpack.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s +// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify %s // expected-no-diagnostics namespace pr12262 { @@ -201,3 +202,24 @@ void func() } } + +#if __cplusplus >= 202002L +namespace GH81436 { + +template struct Bar; + +template +Bar(E) -> Bar; + +template struct Foo {}; + +// Bar doesn't have to be of a complete type. +template +auto func() requires requires(Bar ...init_lists) { + sizeof...(init_lists) > 0; +} {} + +void f() { func(); } + +} // namespace GH81436 +#endif diff --git a/clang/test/CodeGen/AArch64/cpu-supports.c b/clang/test/CodeGen/AArch64/cpu-supports.c index 76fcea0be3158..406201781d480 100644 --- a/clang/test/CodeGen/AArch64/cpu-supports.c +++ b/clang/test/CodeGen/AArch64/cpu-supports.c @@ -18,8 +18,8 @@ // CHECK-NEXT: br label [[RETURN:%.*]] // CHECK: if.end: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 17867063951360 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 17867063951360 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 17936857268992 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 17936857268992 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label [[IF_THEN1:%.*]], label [[IF_END2:%.*]] // CHECK: if.then1: @@ -27,8 +27,8 @@ // CHECK-NEXT: br label [[RETURN]] // CHECK: if.end2: // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 171136785840078848 -// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 171136785840078848 +// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 171141184020873984 +// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 171141184020873984 // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] // CHECK-NEXT: br i1 [[TMP11]], label [[IF_THEN3:%.*]], label [[IF_END4:%.*]] // CHECK: if.then3: diff --git a/clang/test/CodeGen/AArch64/fixed-register-global.c b/clang/test/CodeGen/AArch64/fixed-register-global.c new file mode 100644 index 0000000000000..25c7aa254547b --- /dev/null +++ b/clang/test/CodeGen/AArch64/fixed-register-global.c @@ -0,0 +1,23 @@ +/// Check that -ffixed register handled for globals. +/// Regression test for #76426, #109778 +// REQUIRES: aarch64-registered-target + +// RUN: %clang -c --target=aarch64-none-gnu -ffixed-x15 %s -o /dev/null 2>&1 | count 0 + +// RUN: not %clang -c --target=aarch64-none-gnu %s -o /dev/null 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR_INVREG +// ERR_INVREG: error: register 'x15' unsuitable for global register variables on this target + +// RUN: not %clang -c --target=aarch64-none-gnu -ffixed-x15 -DTYPE=short %s -o /dev/null 2>&1 | \ +// RUN: FileCheck %s --check-prefix=ERR_SIZE +// ERR_SIZE: error: size of register 'x15' does not match variable size + +#ifndef TYPE +#define TYPE long +#endif + +register TYPE x15 __asm__("x15"); + +TYPE foo() { + return x15; +} diff --git a/clang/test/CodeGen/AArch64/fmv-dependencies.c b/clang/test/CodeGen/AArch64/fmv-dependencies.c index f74b7aa32c7dc..3a524b89496e0 100644 --- a/clang/test/CodeGen/AArch64/fmv-dependencies.c +++ b/clang/test/CodeGen/AArch64/fmv-dependencies.c @@ -183,10 +183,10 @@ int caller() { // CHECK: attributes #[[sha2]] = { {{.*}} "target-features"="+fmv,+fp-armv8,+neon,+outline-atomics,+sha2,+v8a" // CHECK: attributes #[[sha3]] = { {{.*}} "target-features"="+fmv,+fp-armv8,+neon,+outline-atomics,+sha2,+sha3,+v8a" // CHECK: attributes #[[sm4]] = { {{.*}} "target-features"="+fmv,+fp-armv8,+neon,+outline-atomics,+sm4,+v8a" -// CHECK: attributes #[[sme]] = { {{.*}} "target-features"="+bf16,+fmv,+fp-armv8,+neon,+outline-atomics,+sme,+v8a" -// CHECK: attributes #[[sme_f64f64]] = { {{.*}} "target-features"="+bf16,+fmv,+fp-armv8,+neon,+outline-atomics,+sme,+sme-f64f64,+v8a" -// CHECK: attributes #[[sme_i16i64]] = { {{.*}} "target-features"="+bf16,+fmv,+fp-armv8,+neon,+outline-atomics,+sme,+sme-i16i64,+v8a" -// CHECK: attributes #[[sme2]] = { {{.*}} "target-features"="+bf16,+fmv,+fp-armv8,+neon,+outline-atomics,+sme,+sme2,+v8a" +// CHECK: attributes #[[sme]] = { {{.*}} "target-features"="+bf16,+fmv,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sme,+v8a" +// CHECK: attributes #[[sme_f64f64]] = { {{.*}} "target-features"="+bf16,+fmv,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sme,+sme-f64f64,+v8a" +// CHECK: attributes #[[sme_i16i64]] = { {{.*}} "target-features"="+bf16,+fmv,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sme,+sme-i16i64,+v8a" +// CHECK: attributes #[[sme2]] = { {{.*}} "target-features"="+bf16,+fmv,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sme,+sme2,+v8a" // CHECK: attributes #[[ssbs]] = { {{.*}} "target-features"="+fmv,+fp-armv8,+neon,+outline-atomics,+ssbs,+v8a" // CHECK: attributes #[[sve]] = { {{.*}} "target-features"="+fmv,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+v8a" // CHECK: attributes #[[sve2]] = { {{.*}} "target-features"="+fmv,+fp-armv8,+fullfp16,+neon,+outline-atomics,+sve,+sve2,+v8a" diff --git a/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sme2_fp8_cvt.c b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sme2_fp8_cvt.c index 5ba76671ff5d5..ae2e780f84cfe 100644 --- a/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sme2_fp8_cvt.c +++ b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sme2_fp8_cvt.c @@ -16,6 +16,134 @@ #define SVE_ACLE_FUNC(A1,A2,A3) A1##A2##A3 #endif +// CHECK-LABEL: @test_cvt_f16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt.x2.nxv8f16( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z15test_cvt_f16_x213svfloat16x2_tm( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt.x2.nxv8f16( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svmfloat8_t test_cvt_f16_x2(svfloat16x2_t zn, fpm_t fpmr) __arm_streaming { + return SVE_ACLE_FUNC(svcvt_mf8,_f16_x2,_fpm)(zn, fpmr); +} + +// CHECK-LABEL: @test_cvt_f32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt.x4( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z15test_cvt_f32_x413svfloat32x4_tm( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt.x4( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svmfloat8_t test_cvt_f32_x4(svfloat32x4_t zn, fpm_t fpmr) __arm_streaming { + return SVE_ACLE_FUNC(svcvt_mf8,_f32_x4,_fpm)(zn, fpmr); +} + +// CHECK-LABEL: @test_cvtn_f32_x4( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtn.x4( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z16test_cvtn_f32_x413svfloat32x4_tm( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtn.x4( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svmfloat8_t test_cvtn_f32_x4(svfloat32x4_t zn, fpm_t fpmr) __arm_streaming { + return SVE_ACLE_FUNC(svcvtn_mf8,_f32_x4,_fpm)(zn, fpmr); +} + +// CHECK-LABEL: @test_cvt_bf16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt.x2.nxv8bf16( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z16test_cvt_bf16_x214svbfloat16x2_tm( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt.x2.nxv8bf16( [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]]) +// CPP-CHECK-NEXT: ret [[TMP0]] +// +svmfloat8_t test_cvt_bf16_x2(svbfloat16x2_t zn, fpm_t fpmr) __arm_streaming { + return SVE_ACLE_FUNC(svcvt_mf8,_bf16_x2,_fpm)(zn, fpmr); +} + +// CHECK-LABEL: @test_cvt1_f16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.fp8.cvt1.x2.nxv8f16( [[ZN:%.*]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z16test_cvt1_f16_x2u13__SVMfloat8_tm( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.fp8.cvt1.x2.nxv8f16( [[ZN:%.*]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svfloat16x2_t test_cvt1_f16_x2(svmfloat8_t zn, fpm_t fpmr) __arm_streaming { + return SVE_ACLE_FUNC(svcvt1_f16,_mf8,_x2_fpm)(zn, fpmr); +} + +// CHECK-LABEL: @test_cvt2_f16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.fp8.cvt2.x2.nxv8f16( [[ZN:%.*]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z16test_cvt2_f16_x2u13__SVMfloat8_tm( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.fp8.cvt2.x2.nxv8f16( [[ZN:%.*]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svfloat16x2_t test_cvt2_f16_x2(svmfloat8_t zn, fpm_t fpmr) __arm_streaming { + return SVE_ACLE_FUNC(svcvt2_f16,_mf8,_x2_fpm)(zn, fpmr); +} + +// CHECK-LABEL: @test_cvt1_bf16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.fp8.cvt1.x2.nxv8bf16( [[ZN:%.*]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z17test_cvt1_bf16_x2u13__SVMfloat8_tm( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.fp8.cvt1.x2.nxv8bf16( [[ZN:%.*]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svbfloat16x2_t test_cvt1_bf16_x2(svmfloat8_t zn, fpm_t fpmr) __arm_streaming { + return SVE_ACLE_FUNC(svcvt1_bf16,_mf8,_x2_fpm)(zn, fpmr); +} + +// CHECK-LABEL: @test_cvt2_bf16_x2( +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.fp8.cvt2.x2.nxv8bf16( [[ZN:%.*]]) +// CHECK-NEXT: ret { , } [[TMP0]] +// +// CPP-CHECK-LABEL: @_Z17test_cvt2_bf16_x2u13__SVMfloat8_tm( +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) +// CPP-CHECK-NEXT: [[TMP0:%.*]] = tail call { , } @llvm.aarch64.sve.fp8.cvt2.x2.nxv8bf16( [[ZN:%.*]]) +// CPP-CHECK-NEXT: ret { , } [[TMP0]] +// +svbfloat16x2_t test_cvt2_bf16_x2(svmfloat8_t zn, fpm_t fpmr) __arm_streaming { + return SVE_ACLE_FUNC(svcvt2_bf16,_mf8,_x2_fpm)(zn, fpmr); +} + // CHECK-LABEL: @test_cvtl1_f16_x2( // CHECK-NEXT: entry: // CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR:%.*]]) diff --git a/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sme2_fp8_fmopa.c b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sme2_fp8_fmopa.c new file mode 100644 index 0000000000000..95d6383ab30ef --- /dev/null +++ b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sme2_fp8_fmopa.c @@ -0,0 +1,55 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// REQUIRES: aarch64-registered-target + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme-f8f16 -target-feature +sme-f8f32 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3) A1##A2##A3 +#endif + + +// CHECK-LABEL: define dso_local void @test_svmopa_za16_mf8_m( +// CHECK-SAME: [[PN:%.*]], [[PM:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmopa.za16(i32 1, [[PN]], [[PM]], [[ZN]], [[ZM]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z22test_svmopa_za16_mf8_mu10__SVBool_tS_u13__SVMfloat8_tS0_m( +// CPP-CHECK-SAME: [[PN:%.*]], [[PM:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0:[0-9]+]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmopa.za16(i32 1, [[PN]], [[PM]], [[ZN]], [[ZM]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmopa_za16_mf8_m(svbool_t pn, svbool_t pm, svmfloat8_t zn, + svmfloat8_t zm, fpm_t fpmr) __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svmopa_za16,_mf8,_m_fpm)(1, pn, pm, zn, zm, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svmopa_za32_mf8_m( +// CHECK-SAME: [[PN:%.*]], [[PM:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmopa.za32(i32 3, [[PN]], [[PM]], [[ZN]], [[ZM]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z22test_svmopa_za32_mf8_mu10__SVBool_tS_u13__SVMfloat8_tS0_m( +// CPP-CHECK-SAME: [[PN:%.*]], [[PM:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmopa.za32(i32 3, [[PN]], [[PM]], [[ZN]], [[ZM]]) +// CPP-CHECK-NEXT: ret void +// +void test_svmopa_za32_mf8_m(svbool_t pn, svbool_t pm, svmfloat8_t zn, + svmfloat8_t zm, fpm_t fpmr) __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svmopa_za32,_mf8,_m_fpm)(3, pn, pm, zn, zm, fpmr); +} diff --git a/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sme2_fp8_mla.c b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sme2_fp8_mla.c new file mode 100644 index 0000000000000..722ccc9f5d5b0 --- /dev/null +++ b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sme2_fp8_mla.c @@ -0,0 +1,129 @@ + +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// REQUIRES: aarch64-registered-target + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -DSME_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -DSME_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes=mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme-f8f16 -target-feature +sme-f8f32 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +#include + +#ifdef SME_OVERLOADED_FORMS +#define SME_ACLE_FUNC(A1,A2_UNUSED,A3) A1##A3 +#else +#define SME_ACLE_FUNC(A1,A2,A3) A1##A2##A3 +#endif + +// FMLAL (indexed) + +// CHECK-LABEL: define dso_local void @test_svmla_lane_za16_vg2x1( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmlal.lane.za16.vg2x1(i32 [[SLICE]], [[ZN]], [[ZM]], i32 0) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z26test_svmla_lane_za16_vg2x1ju13__SVMfloat8_tS_m( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmlal.lane.za16.vg2x1(i32 [[SLICE]], [[ZN]], [[ZM]], i32 0) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane_za16_vg2x1(uint32_t slice, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) __arm_streaming __arm_inout("za") { + SME_ACLE_FUNC(svmla_lane_za16,_mf8,_vg2x1_fpm)(slice, zn, zm, 0, fpm); +} + +// CHECK-LABEL: define dso_local void @test_svmla_lane_za16_vg2x2( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmlal.lane.za16.vg2x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z26test_svmla_lane_za16_vg2x2j13svmfloat8x2_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmlal.lane.za16.vg2x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane_za16_vg2x2(uint32_t slice, svmfloat8x2_t zn, svmfloat8_t zm, fpm_t fpm) __arm_streaming __arm_inout("za") { + SME_ACLE_FUNC(svmla_lane_za16,_mf8,_vg2x2_fpm)(slice, zn, zm, 15, fpm); +} + +// CHECK-LABEL: define dso_local void @test_svmla_lane_za16_vg2x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmlal.lane.za16.vg2x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z26test_svmla_lane_za16_vg2x4j13svmfloat8x4_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmlal.lane.za16.vg2x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane_za16_vg2x4(uint32_t slice, svmfloat8x4_t zn, svmfloat8_t zm, fpm_t fpm) __arm_streaming __arm_inout("za") { + SME_ACLE_FUNC(svmla_lane_za16,_mf8,_vg2x4_fpm)(slice, zn, zm, 7, fpm); +} + +// FMLALL (indexed) + +// CHECK-LABEL: define dso_local void @test_svmla_lane_za32_vg4x1( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmlall.lane.za32.vg4x1(i32 [[SLICE]], [[ZN]], [[ZM]], i32 0) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z26test_svmla_lane_za32_vg4x1ju13__SVMfloat8_tS_m( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmlall.lane.za32.vg4x1(i32 [[SLICE]], [[ZN]], [[ZM]], i32 0) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane_za32_vg4x1(uint32_t slice, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) __arm_streaming __arm_inout("za") { + SME_ACLE_FUNC(svmla_lane_za32,_mf8,_vg4x1_fpm)(slice, zn, zm, 0, fpm); +} + +// CHECK-LABEL: define dso_local void @test_svmla_lane_za32_vg4x2( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmlall.lane.za32.vg4x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 15) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z26test_svmla_lane_za32_vg4x2j13svmfloat8x2_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmlall.lane.za32.vg4x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 15) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane_za32_vg4x2(uint32_t slice, svmfloat8x2_t zn, svmfloat8_t zm, fpm_t fpm) __arm_streaming __arm_inout("za") { + SME_ACLE_FUNC(svmla_lane_za32,_mf8,_vg4x2_fpm)(slice, zn, zm, 15, fpm); +} + +// CHECK-LABEL: define dso_local void @test_svmla_lane_za32_vg4x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmlall.lane.za32.vg4x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z26test_svmla_lane_za32_vg4x4j13svmfloat8x4_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fmlall.lane.za32.vg4x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svmla_lane_za32_vg4x4(uint32_t slice, svmfloat8x4_t zn, svmfloat8_t zm, fpm_t fpm) __arm_streaming __arm_inout("za") { + SME_ACLE_FUNC(svmla_lane_za32,_mf8,_vg4x4_fpm)(slice, zn, zm, 7, fpm); +} \ No newline at end of file diff --git a/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sve2_fp8_cvt.c b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sve2_fp8_cvt.c new file mode 100644 index 0000000000000..c026b8aa216f3 --- /dev/null +++ b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sve2_fp8_cvt.c @@ -0,0 +1,173 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +fp8 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +fp8 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CHECK-CXX + +// RUN: %clang_cc1 -DSME_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +fp8 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -DSME_OVERLOADED_FORMS -x c++ -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +fp8 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CHECK-CXX + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +fp8 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +fp8 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +// REQUIRES: aarch64-registered-target + +#ifdef __ARM_FEATURE_SME +#include +#else +#include +#endif + +#ifdef SVE_OVERLOADED_FORMS +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3) A1##A2##A3 +#endif + +#ifdef __ARM_FEATURE_SME +#define STREAMING __arm_streaming +#else +#define STREAMING +#endif + +// CHECK-LABEL: define dso_local @test_svcvt1_bf16_mf8( +// CHECK-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt1.nxv8bf16( [[ZN]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z20test_svcvt1_bf16_mf8u13__SVMfloat8_tm( +// CHECK-CXX-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt1.nxv8bf16( [[ZN]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svbfloat16_t test_svcvt1_bf16_mf8(svmfloat8_t zn, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svcvt1_bf16,_mf8,_fpm)(zn, fpm); +} + +// CHECK-LABEL: define dso_local @test_svcvt2_bf16_mf8( +// CHECK-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt2.nxv8bf16( [[ZN]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z20test_svcvt2_bf16_mf8u13__SVMfloat8_tm( +// CHECK-CXX-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt2.nxv8bf16( [[ZN]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svbfloat16_t test_svcvt2_bf16_mf8(svmfloat8_t zn, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svcvt2_bf16,_mf8,_fpm)(zn, fpm); +} + +// CHECK-LABEL: define dso_local @test_svcvtlt1_bf16_mf8( +// CHECK-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtlt1.nxv8bf16( [[ZN]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z22test_svcvtlt1_bf16_mf8u13__SVMfloat8_tm( +// CHECK-CXX-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtlt1.nxv8bf16( [[ZN]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svbfloat16_t test_svcvtlt1_bf16_mf8(svmfloat8_t zn, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svcvtlt1_bf16,_mf8,_fpm)(zn, fpm); +} + +// CHECK-LABEL: define dso_local @test_svcvtlt2_bf16_mf8( +// CHECK-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtlt2.nxv8bf16( [[ZN]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z22test_svcvtlt2_bf16_mf8u13__SVMfloat8_tm( +// CHECK-CXX-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtlt2.nxv8bf16( [[ZN]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svbfloat16_t test_svcvtlt2_bf16_mf8(svmfloat8_t zn, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svcvtlt2_bf16,_mf8,_fpm)(zn, fpm); +} + +// CHECK-LABEL: define dso_local @test_svcvt1_f16_mf8( +// CHECK-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt1.nxv8f16( [[ZN]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z19test_svcvt1_f16_mf8u13__SVMfloat8_tm( +// CHECK-CXX-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt1.nxv8f16( [[ZN]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat16_t test_svcvt1_f16_mf8(svmfloat8_t zn, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svcvt1_f16,_mf8,_fpm)(zn, fpm); +} + +// CHECK-LABEL: define dso_local @test_svcvt2_f16_mf8( +// CHECK-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt2.nxv8f16( [[ZN]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z19test_svcvt2_f16_mf8u13__SVMfloat8_tm( +// CHECK-CXX-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvt2.nxv8f16( [[ZN]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat16_t test_svcvt2_f16_mf8(svmfloat8_t zn, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svcvt2_f16,_mf8,_fpm)(zn, fpm); +} + +// CHECK-LABEL: define dso_local @test_svcvtlt1_f16_mf8( +// CHECK-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtlt1.nxv8f16( [[ZN]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z21test_svcvtlt1_f16_mf8u13__SVMfloat8_tm( +// CHECK-CXX-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtlt1.nxv8f16( [[ZN]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat16_t test_svcvtlt1_f16_mf8(svmfloat8_t zn, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svcvtlt1_f16,_mf8,_fpm)(zn, fpm); +} + +// CHECK-LABEL: define dso_local @test_svcvtlt2_f16_mf8( +// CHECK-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtlt2.nxv8f16( [[ZN]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z21test_svcvtlt2_f16_mf8u13__SVMfloat8_tm( +// CHECK-CXX-SAME: [[ZN:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtlt2.nxv8f16( [[ZN]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat16_t test_svcvtlt2_f16_mf8(svmfloat8_t zn, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svcvtlt2_f16,_mf8,_fpm)(zn, fpm); +} diff --git a/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sve2_fp8_cvtn.c b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sve2_fp8_cvtn.c new file mode 100644 index 0000000000000..ed5b0ce02af4b --- /dev/null +++ b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sve2_fp8_cvtn.c @@ -0,0 +1,101 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +fp8 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +fp8 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CHECK-CXX + +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +fp8 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -x c++ -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +fp8 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CHECK-CXX + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +fp8 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +fp8 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +// REQUIRES: aarch64-registered-target + +#ifdef __ARM_FEATURE_SME +#include +#else +#include +#endif + +#ifdef SVE_OVERLOADED_FORMS +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3) A1##A2##A3 +#endif + +#ifdef __ARM_FEATURE_SME +#define STREAMING __arm_streaming +#else +#define STREAMING +#endif + +// CHECK-LABEL: define dso_local @test_svcvtn_f8_bf16( +// CHECK-SAME: [[ZN_ZM_COERCE0:%.*]], [[ZN_ZM_COERCE1:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtn.nxv8bf16( [[ZN_ZM_COERCE0]], [[ZN_ZM_COERCE1]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z19test_svcvtn_f8_bf1614svbfloat16x2_tm( +// CHECK-CXX-SAME: [[ZN_ZM_COERCE0:%.*]], [[ZN_ZM_COERCE1:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtn.nxv8bf16( [[ZN_ZM_COERCE0]], [[ZN_ZM_COERCE1]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svcvtn_f8_bf16(svbfloat16x2_t zn_zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svcvtn_mf8,_bf16_x2,_fpm)(zn_zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svcvtn_f8_f16( +// CHECK-SAME: [[ZN_ZM_COERCE0:%.*]], [[ZN_ZM_COERCE1:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtn.nxv8f16( [[ZN_ZM_COERCE0]], [[ZN_ZM_COERCE1]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z18test_svcvtn_f8_f1613svfloat16x2_tm( +// CHECK-CXX-SAME: [[ZN_ZM_COERCE0:%.*]], [[ZN_ZM_COERCE1:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtn.nxv8f16( [[ZN_ZM_COERCE0]], [[ZN_ZM_COERCE1]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svcvtn_f8_f16(svfloat16x2_t zn_zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svcvtn_mf8,_f16_x2,_fpm)(zn_zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svcvtnb_f8_f32( +// CHECK-SAME: [[ZN_ZM_COERCE0:%.*]], [[ZN_ZM_COERCE1:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtnb.nxv4f32( [[ZN_ZM_COERCE0]], [[ZN_ZM_COERCE1]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z19test_svcvtnb_f8_f3213svfloat32x2_tm( +// CHECK-CXX-SAME: [[ZN_ZM_COERCE0:%.*]], [[ZN_ZM_COERCE1:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtnb.nxv4f32( [[ZN_ZM_COERCE0]], [[ZN_ZM_COERCE1]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svcvtnb_f8_f32(svfloat32x2_t zn_zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svcvtnb_mf8,_f32_x2,_fpm)(zn_zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svcvtnt_f8_f32( +// CHECK-SAME: [[ZD:%.*]], [[ZN_ZM_COERCE0:%.*]], [[ZN_ZM_COERCE1:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtnt.nxv4f32( [[ZD]], [[ZN_ZM_COERCE0]], [[ZN_ZM_COERCE1]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z19test_svcvtnt_f8_f32u13__SVMfloat8_t13svfloat32x2_tm( +// CHECK-CXX-SAME: [[ZD:%.*]], [[ZN_ZM_COERCE0:%.*]], [[ZN_ZM_COERCE1:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.cvtnt.nxv4f32( [[ZD]], [[ZN_ZM_COERCE0]], [[ZN_ZM_COERCE1]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svmfloat8_t test_svcvtnt_f8_f32(svmfloat8_t zd, svfloat32x2_t zn_zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svcvtnt_mf8,_f32_x2,_fpm)(zd, zn_zm, fpm); +} diff --git a/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sve2_fp8_fdot.c b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sve2_fp8_fdot.c new file mode 100644 index 0000000000000..950a19115811e --- /dev/null +++ b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sve2_fp8_fdot.c @@ -0,0 +1,149 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +fp8 -target-feature +fp8dot2 -target-feature +fp8dot4 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +fp8 -target-feature +ssve-fp8dot2 -target-feature +ssve-fp8dot4 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CHECK-CXX + +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +fp8 -target-feature +fp8dot2 -target-feature +fp8dot4 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -x c++ -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +fp8 -target-feature +ssve-fp8dot2 -target-feature +ssve-fp8dot4 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CHECK-CXX + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +fp8 -target-feature +fp8dot2 -target-feature +fp8dot4 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +fp8 -target-feature +ssve-fp8dot2 -target-feature +ssve-fp8dot4 -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +// REQUIRES: aarch64-registered-target + +#ifdef __ARM_FEATURE_SME +#include +#else +#include +#endif + +#ifdef SVE_OVERLOADED_FORMS +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3) A1##A2##A3 +#endif + +#ifdef __ARM_FEATURE_SME +#define STREAMING __arm_streaming +#else +#define STREAMING +#endif + +// CHECK-LABEL: define dso_local @test_svdot_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fdot.nxv4f32( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z18test_svdot_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fdot.nxv4f32( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat32_t test_svdot_f32_mf8(svfloat32_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svdot,_f32_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svdot_n_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fdot.nxv4f32( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CXX-LABEL: define dso_local @_Z20test_svdot_n_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tu6__mfp8m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fdot.nxv4f32( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-CXX-NEXT: ret [[TMP1]] +// +svfloat32_t test_svdot_n_f32_mf8(svfloat32_t zda, svmfloat8_t zn, mfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svdot,_n_f32_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svdot_f16_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fdot.nxv8f16( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z18test_svdot_f16_mf8u13__SVFloat16_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fdot.nxv8f16( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat16_t test_svdot_f16_mf8(svfloat16_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svdot,_f16_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svdot_n_f16_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fdot.nxv8f16( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CXX-LABEL: define dso_local @_Z20test_svdot_n_f16_mf8u13__SVFloat16_tu13__SVMfloat8_tu6__mfp8m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fdot.nxv8f16( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-CXX-NEXT: ret [[TMP1]] +// +svfloat16_t test_svdot_n_f16_mf8(svfloat16_t zda, svmfloat8_t zn, mfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svdot,_n_f16_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svdot_lane_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fdot.lane.nxv4f32( [[ZDA]], [[ZN]], [[ZM]], i32 3) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z23test_svdot_lane_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fdot.lane.nxv4f32( [[ZDA]], [[ZN]], [[ZM]], i32 3) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat32_t test_svdot_lane_f32_mf8(svfloat32_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svdot_lane,_f32_mf8,_fpm)(zda, zn, zm, 3, fpm); +} + +// CHECK-LABEL: define dso_local @test_svdot_lane_f16_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fdot.lane.nxv8f16( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z23test_svdot_lane_f16_mf8u13__SVFloat16_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fdot.lane.nxv8f16( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat16_t test_svdot_lane_f16_mf8(svfloat16_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svdot_lane,_f16_mf8,_fpm)(zda, zn, zm, 7, fpm); +} diff --git a/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sve2_fp8_fmla.c b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sve2_fp8_fmla.c new file mode 100644 index 0000000000000..425e6a57ffe3c --- /dev/null +++ b/clang/test/CodeGen/AArch64/fp8-intrinsics/acle_sve2_fp8_fmla.c @@ -0,0 +1,389 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +fp8 -target-feature +fp8fma -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -x c++ -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +fp8 -target-feature +ssve-fp8fma -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CHECK-CXX + +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +fp8 -target-feature +fp8fma -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -x c++ -DSVE_OVERLOADED_FORMS -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +fp8 -target-feature +ssve-fp8fma -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -p mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CHECK-CXX + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +sve2 -target-feature +fp8 -target-feature +fp8fma -S -disable-O0-optnone -Werror -Wall -o /dev/null %s +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -target-feature +fp8 -target-feature +ssve-fp8fma -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +// REQUIRES: aarch64-registered-target + +#ifdef __ARM_FEATURE_SME +#include +#else +#include +#endif + +#ifdef SVE_OVERLOADED_FORMS +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3) A1##A3 +#else +#define SVE_ACLE_FUNC(A1,A2,A3) A1##A2##A3 +#endif + +#ifdef __ARM_FEATURE_SME +#define STREAMING __arm_streaming +#else +#define STREAMING +#endif + +// CHECK-LABEL: define dso_local @test_svmlalb_f16_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalb.nxv8f16( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z20test_svmlalb_f16_mf8u13__SVFloat16_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalb.nxv8f16( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat16_t test_svmlalb_f16_mf8(svfloat16_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlalb,_f16_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlalb_n_f16_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalb.nxv8f16( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CXX-LABEL: define dso_local @_Z22test_svmlalb_n_f16_mf8u13__SVFloat16_tu13__SVMfloat8_tu6__mfp8m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalb.nxv8f16( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-CXX-NEXT: ret [[TMP1]] +// +svfloat16_t test_svmlalb_n_f16_mf8(svfloat16_t zda, svmfloat8_t zn, mfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlalb,_n_f16_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlalt_f16_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalt.nxv8f16( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z20test_svmlalt_f16_mf8u13__SVFloat16_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalt.nxv8f16( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat16_t test_svmlalt_f16_mf8(svfloat16_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlalt,_f16_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlalt_n_f16_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalt.nxv8f16( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CXX-LABEL: define dso_local @_Z22test_svmlalt_n_f16_mf8u13__SVFloat16_tu13__SVMfloat8_tu6__mfp8m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalt.nxv8f16( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-CXX-NEXT: ret [[TMP1]] +// +svfloat16_t test_svmlalt_n_f16_mf8(svfloat16_t zda, svmfloat8_t zn, mfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlalt,_n_f16_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlalb_lane_f16_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalb.lane.nxv8f16( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z25test_svmlalb_lane_f16_mf8u13__SVFloat16_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalb.lane.nxv8f16( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat16_t test_svmlalb_lane_f16_mf8(svfloat16_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlalb_lane,_f16_mf8,_fpm)(zda, zn, zm, 7, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlalt_lane_f16_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalt.lane.nxv8f16( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z25test_svmlalt_lane_f16_mf8u13__SVFloat16_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalt.lane.nxv8f16( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat16_t test_svmlalt_lane_f16_mf8(svfloat16_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlalt_lane,_f16_mf8,_fpm)(zda, zn, zm, 7, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlallbb_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlallbb.nxv4f32( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z22test_svmlallbb_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlallbb.nxv4f32( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat32_t test_svmlallbb_f32_mf8(svfloat32_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlallbb,_f32_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlallbb_n_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlallbb.nxv4f32( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CXX-LABEL: define dso_local @_Z24test_svmlallbb_n_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tu6__mfp8m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlallbb.nxv4f32( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-CXX-NEXT: ret [[TMP1]] +// +svfloat32_t test_svmlallbb_n_f32_mf8(svfloat32_t zda, svmfloat8_t zn, mfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlallbb,_n_f32_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlallbt_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlallbt.nxv4f32( [[ZDA]], [[ZM]], [[ZM]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z22test_svmlallbt_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlallbt.nxv4f32( [[ZDA]], [[ZM]], [[ZM]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat32_t test_svmlallbt_f32_mf8(svfloat32_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlallbt,_f32_mf8,_fpm)(zda, zm, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlallbt_n_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlallbt.nxv4f32( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CXX-LABEL: define dso_local @_Z24test_svmlallbt_n_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tu6__mfp8m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlallbt.nxv4f32( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-CXX-NEXT: ret [[TMP1]] +// +svfloat32_t test_svmlallbt_n_f32_mf8(svfloat32_t zda, svmfloat8_t zn, mfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlallbt,_n_f32_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlalltb_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalltb.nxv4f32( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z22test_svmlalltb_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalltb.nxv4f32( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat32_t test_svmlalltb_f32_mf8(svfloat32_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlalltb,_f32_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlalltb_n_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalltb.nxv4f32( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CXX-LABEL: define dso_local @_Z24test_svmlalltb_n_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tu6__mfp8m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalltb.nxv4f32( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-CXX-NEXT: ret [[TMP1]] +// +svfloat32_t test_svmlalltb_n_f32_mf8(svfloat32_t zda, svmfloat8_t zn, mfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlalltb,_n_f32_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlalltt_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalltt.nxv4f32( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z22test_svmlalltt_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalltt.nxv4f32( [[ZDA]], [[ZN]], [[ZM]]) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat32_t test_svmlalltt_f32_mf8(svfloat32_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlalltt,_f32_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlalltt_n_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalltt.nxv4f32( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-NEXT: ret [[TMP1]] +// +// CHECK-CXX-LABEL: define dso_local @_Z24test_svmlalltt_n_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tu6__mfp8m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], <1 x i8> [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = extractelement <1 x i8> [[ZM]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement poison, i8 [[TMP0]], i64 0 +// CHECK-CXX-NEXT: [[DOTSPLAT:%.*]] = shufflevector [[DOTSPLATINSERT]], poison, zeroinitializer +// CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalltt.nxv4f32( [[ZDA]], [[ZN]], [[DOTSPLAT]]) +// CHECK-CXX-NEXT: ret [[TMP1]] +// +svfloat32_t test_svmlalltt_n_f32_mf8(svfloat32_t zda, svmfloat8_t zn, mfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlalltt,_n_f32_mf8,_fpm)(zda, zn, zm, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlallbb_lane_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlallbb.lane.nxv4f32( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z27test_svmlallbb_lane_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlallbb.lane.nxv4f32( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat32_t test_svmlallbb_lane_f32_mf8(svfloat32_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlallbb_lane,_f32_mf8,_fpm)(zda, zn, zm, 7, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlallbt_lane_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlallbt.lane.nxv4f32( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z27test_svmlallbt_lane_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlallbt.lane.nxv4f32( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat32_t test_svmlallbt_lane_f32_mf8(svfloat32_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlallbt_lane,_f32_mf8,_fpm)(zda, zn, zm, 7, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlalltb_lane_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalltb.lane.nxv4f32( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z27test_svmlalltb_lane_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalltb.lane.nxv4f32( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat32_t test_svmlalltb_lane_f32_mf8(svfloat32_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlalltb_lane,_f32_mf8,_fpm)(zda, zn, zm, 7, fpm); +} + +// CHECK-LABEL: define dso_local @test_svmlalltt_lane_f32_mf8( +// CHECK-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalltt.lane.nxv4f32( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-NEXT: ret [[TMP0]] +// +// CHECK-CXX-LABEL: define dso_local @_Z27test_svmlalltt_lane_f32_mf8u13__SVFloat32_tu13__SVMfloat8_tS0_m( +// CHECK-CXX-SAME: [[ZDA:%.*]], [[ZN:%.*]], [[ZM:%.*]], i64 noundef [[FPM:%.*]]) #[[ATTR0]] { +// CHECK-CXX-NEXT: [[ENTRY:.*:]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPM]]) +// CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.fp8.fmlalltt.lane.nxv4f32( [[ZDA]], [[ZN]], [[ZM]], i32 7) +// CHECK-CXX-NEXT: ret [[TMP0]] +// +svfloat32_t test_svmlalltt_lane_f32_mf8(svfloat32_t zda, svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) STREAMING { + return SVE_ACLE_FUNC(svmlalltt_lane,_f32_mf8,_fpm)(zda, zn, zm, 7, fpm); +} diff --git a/clang/test/CodeGen/AArch64/ls64-inline-asm.c b/clang/test/CodeGen/AArch64/ls64-inline-asm.c index a01393525bcd4..8aa0684dba14d 100644 --- a/clang/test/CodeGen/AArch64/ls64-inline-asm.c +++ b/clang/test/CodeGen/AArch64/ls64-inline-asm.c @@ -5,7 +5,7 @@ struct foo { unsigned long long x[8]; }; // CHECK-LABEL: @load( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = tail call i512 asm sideeffect "ld64b $0,[$1]", "=r,r,~{memory}"(ptr [[ADDR:%.*]]) #[[ATTR1:[0-9]+]], !srcloc !2 +// CHECK-NEXT: [[TMP0:%.*]] = tail call i512 asm sideeffect "ld64b $0,[$1]", "=r,r,~{memory}"(ptr [[ADDR:%.*]]) #[[ATTR1:[0-9]+]], !srcloc [[META2:![0-9]+]] // CHECK-NEXT: store i512 [[TMP0]], ptr [[OUTPUT:%.*]], align 8 // CHECK-NEXT: ret void // @@ -17,7 +17,7 @@ void load(struct foo *output, void *addr) // CHECK-LABEL: @store( // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i512, ptr [[INPUT:%.*]], align 8 -// CHECK-NEXT: tail call void asm sideeffect "st64b $0,[$1]", "r,r,~{memory}"(i512 [[TMP0]], ptr [[ADDR:%.*]]) #[[ATTR1]], !srcloc !3 +// CHECK-NEXT: tail call void asm sideeffect "st64b $0,[$1]", "r,r,~{memory}"(i512 [[TMP0]], ptr [[ADDR:%.*]]) #[[ATTR1]], !srcloc [[META3:![0-9]+]] // CHECK-NEXT: ret void // void store(const struct foo *input, void *addr) @@ -29,25 +29,25 @@ void store(const struct foo *input, void *addr) // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[IN:%.*]], align 4, !tbaa [[TBAA4:![0-9]+]] // CHECK-NEXT: [[CONV:%.*]] = sext i32 [[TMP0]] to i64 -// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[IN]], i64 4 +// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[IN]], i64 4 // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4, !tbaa [[TBAA4]] // CHECK-NEXT: [[CONV2:%.*]] = sext i32 [[TMP1]] to i64 -// CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds i8, ptr [[IN]], i64 16 +// CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds nuw i8, ptr [[IN]], i64 16 // CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX4]], align 4, !tbaa [[TBAA4]] // CHECK-NEXT: [[CONV5:%.*]] = sext i32 [[TMP2]] to i64 -// CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds i8, ptr [[IN]], i64 64 +// CHECK-NEXT: [[ARRAYIDX7:%.*]] = getelementptr inbounds nuw i8, ptr [[IN]], i64 64 // CHECK-NEXT: [[TMP3:%.*]] = load i32, ptr [[ARRAYIDX7]], align 4, !tbaa [[TBAA4]] // CHECK-NEXT: [[CONV8:%.*]] = sext i32 [[TMP3]] to i64 -// CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds i8, ptr [[IN]], i64 100 +// CHECK-NEXT: [[ARRAYIDX10:%.*]] = getelementptr inbounds nuw i8, ptr [[IN]], i64 100 // CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[ARRAYIDX10]], align 4, !tbaa [[TBAA4]] // CHECK-NEXT: [[CONV11:%.*]] = sext i32 [[TMP4]] to i64 -// CHECK-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds i8, ptr [[IN]], i64 144 +// CHECK-NEXT: [[ARRAYIDX13:%.*]] = getelementptr inbounds nuw i8, ptr [[IN]], i64 144 // CHECK-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX13]], align 4, !tbaa [[TBAA4]] // CHECK-NEXT: [[CONV14:%.*]] = sext i32 [[TMP5]] to i64 -// CHECK-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds i8, ptr [[IN]], i64 196 +// CHECK-NEXT: [[ARRAYIDX16:%.*]] = getelementptr inbounds nuw i8, ptr [[IN]], i64 196 // CHECK-NEXT: [[TMP6:%.*]] = load i32, ptr [[ARRAYIDX16]], align 4, !tbaa [[TBAA4]] // CHECK-NEXT: [[CONV17:%.*]] = sext i32 [[TMP6]] to i64 -// CHECK-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds i8, ptr [[IN]], i64 256 +// CHECK-NEXT: [[ARRAYIDX19:%.*]] = getelementptr inbounds nuw i8, ptr [[IN]], i64 256 // CHECK-NEXT: [[TMP7:%.*]] = load i32, ptr [[ARRAYIDX19]], align 4, !tbaa [[TBAA4]] // CHECK-NEXT: [[CONV20:%.*]] = sext i32 [[TMP7]] to i64 // CHECK-NEXT: [[S_SROA_10_0_INSERT_EXT:%.*]] = zext i64 [[CONV20]] to i512 @@ -72,7 +72,7 @@ void store(const struct foo *input, void *addr) // CHECK-NEXT: [[S_SROA_0_0_INSERT_EXT:%.*]] = zext i64 [[CONV]] to i512 // CHECK-NEXT: [[S_SROA_0_0_INSERT_MASK:%.*]] = or disjoint i512 [[S_SROA_4_0_INSERT_MASK]], [[S_SROA_4_0_INSERT_SHIFT]] // CHECK-NEXT: [[S_SROA_0_0_INSERT_INSERT:%.*]] = or i512 [[S_SROA_0_0_INSERT_MASK]], [[S_SROA_0_0_INSERT_EXT]] -// CHECK-NEXT: tail call void asm sideeffect "st64b $0,[$1]", "r,r,~{memory}"(i512 [[S_SROA_0_0_INSERT_INSERT]], ptr [[ADDR:%.*]]) #[[ATTR1]], !srcloc !8 +// CHECK-NEXT: tail call void asm sideeffect "st64b $0,[$1]", "r,r,~{memory}"(i512 [[S_SROA_0_0_INSERT_INSERT]], ptr [[ADDR:%.*]]) #[[ATTR1]], !srcloc [[META8:![0-9]+]] // CHECK-NEXT: ret void // void store2(int *in, void *addr) diff --git a/clang/test/CodeGen/AArch64/mixed-target-attributes.c b/clang/test/CodeGen/AArch64/mixed-target-attributes.c index bb6fb7eb8862a..1ccb0c6177c8c 100644 --- a/clang/test/CodeGen/AArch64/mixed-target-attributes.c +++ b/clang/test/CodeGen/AArch64/mixed-target-attributes.c @@ -66,24 +66,24 @@ __attribute__((target_version("jscvt"))) int default_def_with_version_decls(void // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1048576 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048576 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1048832 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048832 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: // CHECK-NEXT: ret ptr @explicit_default._Mjscvt // CHECK: resolver_else: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 64 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 64 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 832 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 832 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK: resolver_return1: // CHECK-NEXT: ret ptr @explicit_default._Mrdm // CHECK: resolver_else2: // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 16 -// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 16 +// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 784 +// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 784 // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] // CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] // CHECK: resolver_return3: @@ -140,24 +140,24 @@ __attribute__((target_version("jscvt"))) int default_def_with_version_decls(void // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1048576 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048576 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1048832 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048832 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: // CHECK-NEXT: ret ptr @implicit_default._Mjscvt // CHECK: resolver_else: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 64 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 64 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 832 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 832 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK: resolver_return1: // CHECK-NEXT: ret ptr @implicit_default._Mrdm // CHECK: resolver_else2: // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 16 -// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 16 +// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 784 +// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 784 // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] // CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] // CHECK: resolver_return3: @@ -207,16 +207,16 @@ __attribute__((target_version("jscvt"))) int default_def_with_version_decls(void // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1048576 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048576 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1048832 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048832 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: // CHECK-NEXT: ret ptr @default_def_with_version_decls._Mjscvt // CHECK: resolver_else: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 16 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 16 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 784 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 784 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK: resolver_return1: diff --git a/clang/test/CodeGen/AArch64/pure-scalable-args.c b/clang/test/CodeGen/AArch64/pure-scalable-args.c index f40c944335e4a..a8c3dd9288a5b 100644 --- a/clang/test/CodeGen/AArch64/pure-scalable-args.c +++ b/clang/test/CodeGen/AArch64/pure-scalable-args.c @@ -417,7 +417,7 @@ void test_va_arg(int n, ...) { // CHECK-AAPCS-EMPTY: // CHECK-AAPCS-NEXT: vaarg.on_stack: ; preds = %vaarg.maybe_reg, %entry // CHECK-AAPCS-NEXT: %stack = load ptr, ptr %ap, align 8 -// CHECK-AAPCS-NEXT: %new_stack = getelementptr inbounds i8, ptr %stack, i64 8 +// CHECK-AAPCS-NEXT: %new_stack = getelementptr inbounds nuw i8, ptr %stack, i64 8 // CHECK-AAPCS-NEXT: store ptr %new_stack, ptr %ap, align 8 // CHECK-AAPCS-NEXT: br label %vaarg.end // CHECK-AAPCS-EMPTY: @@ -428,7 +428,7 @@ void test_va_arg(int n, ...) { // CHECK-AAPCS-NEXT: %vaarg.addr = load ptr, ptr %vaargs.addr, align 8 // CHECK-AAPCS-NEXT: %v.sroa.0.0.copyload = load <2 x i8>, ptr %vaarg.addr, align 16 -// CHECK-AAPCS-NEXT: %v.sroa.43.0.vaarg.addr.sroa_idx = getelementptr inbounds i8, ptr %vaarg.addr, i64 48 +// CHECK-AAPCS-NEXT: %v.sroa.43.0.vaarg.addr.sroa_idx = getelementptr inbounds nuw i8, ptr %vaarg.addr, i64 48 // CHECK-AAPCS-NEXT: %v.sroa.43.0.copyload = load <4 x float>, ptr %v.sroa.43.0.vaarg.addr.sroa_idx, align 16 // CHECK-AAPCS-NEXT: call void @llvm.va_end.p0(ptr nonnull %ap) // CHECK-AAPCS-NEXT: %cast.scalable = call @llvm.vector.insert.nxv2i8.v2i8( poison, <2 x i8> %v.sroa.0.0.copyload, i64 0) @@ -445,11 +445,11 @@ void test_va_arg(int n, ...) { // CHECK-DARWIN-NEXT: call void @llvm.lifetime.start.p0(i64 8, ptr nonnull %ap) // CHECK-DARWIN-NEXT: call void @llvm.va_start.p0(ptr nonnull %ap) // CHECK-DARWIN-NEXT: %argp.cur = load ptr, ptr %ap, align 8 -// CHECK-DARWIN-NEXT: %argp.next = getelementptr inbounds i8, ptr %argp.cur, i64 8 +// CHECK-DARWIN-NEXT: %argp.next = getelementptr inbounds nuw i8, ptr %argp.cur, i64 8 // CHECK-DARWIN-NEXT: store ptr %argp.next, ptr %ap, align 8 // CHECK-DARWIN-NEXT: %0 = load ptr, ptr %argp.cur, align 8 // CHECK-DARWIN-NEXT: %v.sroa.0.0.copyload = load <2 x i8>, ptr %0, align 16 -// CHECK-DARWIN-NEXT: %v.sroa.43.0..sroa_idx = getelementptr inbounds i8, ptr %0, i64 48 +// CHECK-DARWIN-NEXT: %v.sroa.43.0..sroa_idx = getelementptr inbounds nuw i8, ptr %0, i64 48 // CHECK-DARWIN-NEXT: %v.sroa.43.0.copyload = load <4 x float>, ptr %v.sroa.43.0..sroa_idx, align 16 // CHECK-DARWIN-NEXT: call void @llvm.va_end.p0(ptr nonnull %ap) // CHECK-DARWIN-NEXT: %cast.scalable = call @llvm.vector.insert.nxv2i8.v2i8( poison, <2 x i8> %v.sroa.0.0.copyload, i64 0) diff --git a/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_ld1_vnum.c b/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_ld1_vnum.c index fcbd17559dc70..fb86690f07f1d 100644 --- a/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_ld1_vnum.c +++ b/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_ld1_vnum.c @@ -12,9 +12,12 @@ // CHECK-C-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP0]], [[VNUM]] // CHECK-C-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP2:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP3:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP3]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[ADD]], 15 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP4]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z23test_svld1_hor_vnum_za8ju10__SVBool_tPKvl( @@ -23,9 +26,12 @@ // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP0]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP2:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP3:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP3]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[ADD]], 15 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP4]]) // CHECK-CXX-NEXT: ret void // void test_svld1_hor_vnum_za8(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_out("za") { @@ -40,9 +46,12 @@ void test_svld1_hor_vnum_za8(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1h.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 7 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1h.horiz( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1h.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 7 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1h.horiz( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[TMP5]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z24test_svld1_hor_vnum_za16ju10__SVBool_tPKvl( @@ -52,9 +61,12 @@ void test_svld1_hor_vnum_za8(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1h.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 7 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1h.horiz( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1h.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 7 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1h.horiz( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[TMP5]]) // CHECK-CXX-NEXT: ret void // void test_svld1_hor_vnum_za16(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_out("za") { @@ -69,9 +81,12 @@ void test_svld1_hor_vnum_za16(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1w.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 3 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1w.horiz( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1w.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 3 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1w.horiz( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[TMP5]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z24test_svld1_hor_vnum_za32ju10__SVBool_tPKvl( @@ -81,9 +96,12 @@ void test_svld1_hor_vnum_za16(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1w.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 3 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1w.horiz( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1w.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 3 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1w.horiz( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[TMP5]]) // CHECK-CXX-NEXT: ret void // void test_svld1_hor_vnum_za32(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_out("za") { @@ -98,9 +116,12 @@ void test_svld1_hor_vnum_za32(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1d.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 1 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1d.horiz( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1d.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 1 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1d.horiz( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[TMP5]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z24test_svld1_hor_vnum_za64ju10__SVBool_tPKvl( @@ -110,9 +131,12 @@ void test_svld1_hor_vnum_za32(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1d.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 1 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1d.horiz( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1d.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 1 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1d.horiz( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[TMP5]]) // CHECK-CXX-NEXT: ret void // void test_svld1_hor_vnum_za64(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_out("za") { @@ -127,8 +151,10 @@ void test_svld1_hor_vnum_za64(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1q.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1q.horiz( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1q.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1q.horiz( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[TMP4]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z25test_svld1_hor_vnum_za128ju10__SVBool_tPKvl( @@ -138,8 +164,10 @@ void test_svld1_hor_vnum_za64(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1q.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1q.horiz( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1q.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1q.horiz( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[TMP4]]) // CHECK-CXX-NEXT: ret void // void test_svld1_hor_vnum_za128(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_out("za") { @@ -153,9 +181,12 @@ void test_svld1_hor_vnum_za128(uint32_t slice_base, svbool_t pg, const void *ptr // CHECK-C-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP0]], [[VNUM]] // CHECK-C-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP2:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP3:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP3]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[ADD]], 15 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP4]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z22test_svld1_ver_hor_za8ju10__SVBool_tPKvl( @@ -164,9 +195,12 @@ void test_svld1_hor_vnum_za128(uint32_t slice_base, svbool_t pg, const void *ptr // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP0]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP2:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP3:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP3]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[ADD]], 15 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP4]]) // CHECK-CXX-NEXT: ret void // void test_svld1_ver_hor_za8(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_out("za") { @@ -181,9 +215,12 @@ void test_svld1_ver_hor_za8(uint32_t slice_base, svbool_t pg, const void *ptr, i // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1h.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 7 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1h.vert( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1h.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 7 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1h.vert( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[TMP5]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z24test_svld1_ver_vnum_za16ju10__SVBool_tPKvl( @@ -193,9 +230,12 @@ void test_svld1_ver_hor_za8(uint32_t slice_base, svbool_t pg, const void *ptr, i // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1h.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 7 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1h.vert( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1h.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 7 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1h.vert( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[TMP5]]) // CHECK-CXX-NEXT: ret void // void test_svld1_ver_vnum_za16(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_out("za") { @@ -210,9 +250,12 @@ void test_svld1_ver_vnum_za16(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1w.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 3 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1w.vert( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1w.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 3 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1w.vert( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[TMP5]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z24test_svld1_ver_vnum_za32ju10__SVBool_tPKvl( @@ -222,9 +265,12 @@ void test_svld1_ver_vnum_za16(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1w.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 3 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1w.vert( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1w.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 3 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1w.vert( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[TMP5]]) // CHECK-CXX-NEXT: ret void // void test_svld1_ver_vnum_za32(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_out("za") { @@ -239,9 +285,12 @@ void test_svld1_ver_vnum_za32(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1d.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 1 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1d.vert( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1d.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 1 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1d.vert( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[TMP5]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z24test_svld1_ver_vnum_za64ju10__SVBool_tPKvl( @@ -251,9 +300,12 @@ void test_svld1_ver_vnum_za32(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1d.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 1 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1d.vert( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1d.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 1 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1d.vert( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[TMP5]]) // CHECK-CXX-NEXT: ret void // void test_svld1_ver_vnum_za64(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_out("za") { @@ -268,8 +320,10 @@ void test_svld1_ver_vnum_za64(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1q.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1q.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.ld1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[TMP4]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z25test_svld1_ver_vnum_za128ju10__SVBool_tPKvl( @@ -279,8 +333,10 @@ void test_svld1_ver_vnum_za64(uint32_t slice_base, svbool_t pg, const void *ptr, // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1q.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1q.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.ld1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[TMP4]]) // CHECK-CXX-NEXT: ret void // void test_svld1_ver_vnum_za128(uint32_t slice_base, svbool_t pg, const void *ptr, int64_t vnum) __arm_streaming __arm_out("za") { diff --git a/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_st1_vnum.c b/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_st1_vnum.c index b2c609b7c2242..dafc3d61a05f1 100644 --- a/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_st1_vnum.c +++ b/clang/test/CodeGen/AArch64/sme-intrinsics/acle_sme_st1_vnum.c @@ -12,9 +12,12 @@ // CHECK-C-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP0]], [[VNUM]] // CHECK-C-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP2:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP3:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP3]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[ADD]], 15 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP4]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z23test_svst1_hor_vnum_za8ju10__SVBool_tPvl( @@ -23,9 +26,12 @@ // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP0]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP2:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP3:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP3]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[ADD]], 15 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1b.horiz( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP4]]) // CHECK-CXX-NEXT: ret void // void test_svst1_hor_vnum_za8(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_in("za") { @@ -40,9 +46,12 @@ void test_svst1_hor_vnum_za8(uint32_t slice_base, svbool_t pg, void *ptr, int64_ // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1h.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 7 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1h.horiz( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1h.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 7 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1h.horiz( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[TMP5]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z24test_svst1_hor_vnum_za16ju10__SVBool_tPvl( @@ -52,9 +61,12 @@ void test_svst1_hor_vnum_za8(uint32_t slice_base, svbool_t pg, void *ptr, int64_ // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1h.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 7 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1h.horiz( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1h.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 7 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1h.horiz( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[TMP5]]) // CHECK-CXX-NEXT: ret void // void test_svst1_hor_vnum_za16(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_in("za") { @@ -69,9 +81,12 @@ void test_svst1_hor_vnum_za16(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1w.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 3 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1w.horiz( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1w.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 3 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1w.horiz( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[TMP5]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z24test_svst1_hor_vnum_za32ju10__SVBool_tPvl( @@ -81,9 +96,12 @@ void test_svst1_hor_vnum_za16(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1w.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 3 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1w.horiz( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1w.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 3 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1w.horiz( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[TMP5]]) // CHECK-CXX-NEXT: ret void // void test_svst1_hor_vnum_za32(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_in("za") { @@ -98,9 +116,12 @@ void test_svst1_hor_vnum_za32(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1d.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 1 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1d.horiz( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1d.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 1 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1d.horiz( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[TMP5]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z24test_svst1_hor_vnum_za64ju10__SVBool_tPvl( @@ -110,9 +131,12 @@ void test_svst1_hor_vnum_za32(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1d.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 1 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1d.horiz( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1d.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 1 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1d.horiz( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[TMP5]]) // CHECK-CXX-NEXT: ret void // void test_svst1_hor_vnum_za64(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_in("za") { @@ -127,8 +151,10 @@ void test_svst1_hor_vnum_za64(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1q.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1q.horiz( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1q.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1q.horiz( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[TMP4]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z25test_svst1_hor_vnum_za128ju10__SVBool_tPvl( @@ -138,8 +164,10 @@ void test_svst1_hor_vnum_za64(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1q.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1q.horiz( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1q.horiz( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1q.horiz( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[TMP4]]) // CHECK-CXX-NEXT: ret void // void test_svst1_hor_vnum_za128(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_in("za") { @@ -153,9 +181,12 @@ void test_svst1_hor_vnum_za128(uint32_t slice_base, svbool_t pg, void *ptr, int6 // CHECK-C-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP0]], [[VNUM]] // CHECK-C-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP2:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP3:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP3]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[ADD]], 15 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP4]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z23test_svst1_ver_vnum_za8ju10__SVBool_tPvl( @@ -164,9 +195,12 @@ void test_svst1_hor_vnum_za128(uint32_t slice_base, svbool_t pg, void *ptr, int6 // CHECK-CXX-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP0]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP1:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 15 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP2:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP3:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP3]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP2]] +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[ADD]], 15 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1b.vert( [[PG]], ptr [[TMP1]], i32 0, i32 [[TMP4]]) // CHECK-CXX-NEXT: ret void // void test_svst1_ver_vnum_za8(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_in("za") { @@ -181,9 +215,12 @@ void test_svst1_ver_vnum_za8(uint32_t slice_base, svbool_t pg, void *ptr, int64_ // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1h.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 7 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1h.vert( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1h.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 7 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1h.vert( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[TMP5]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z24test_svst1_ver_vnum_za16ju10__SVBool_tPvl( @@ -193,9 +230,12 @@ void test_svst1_ver_vnum_za8(uint32_t slice_base, svbool_t pg, void *ptr, int64_ // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1h.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 7 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1h.vert( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1h.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 7 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1h.vert( [[TMP0]], ptr [[TMP2]], i32 1, i32 [[TMP5]]) // CHECK-CXX-NEXT: ret void // void test_svst1_ver_vnum_za16(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_in("za") { @@ -210,9 +250,12 @@ void test_svst1_ver_vnum_za16(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1w.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 3 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1w.vert( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1w.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 3 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1w.vert( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[TMP5]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z24test_svst1_ver_vnum_za32ju10__SVBool_tPvl( @@ -222,9 +265,12 @@ void test_svst1_ver_vnum_za16(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1w.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 3 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1w.vert( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1w.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 3 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1w.vert( [[TMP0]], ptr [[TMP2]], i32 3, i32 [[TMP5]]) // CHECK-CXX-NEXT: ret void // void test_svst1_ver_vnum_za32(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_in("za") { @@ -239,9 +285,12 @@ void test_svst1_ver_vnum_za32(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1d.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 1 -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1d.vert( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[ADD]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1d.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 1 +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1d.vert( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[TMP5]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z24test_svst1_ver_vnum_za64ju10__SVBool_tPvl( @@ -251,9 +300,12 @@ void test_svst1_ver_vnum_za32(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1d.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], 1 -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1d.vert( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[ADD]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1d.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: [[ADD:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: [[TMP5:%.*]] = add i32 [[ADD]], 1 +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1d.vert( [[TMP0]], ptr [[TMP2]], i32 7, i32 [[TMP5]]) // CHECK-CXX-NEXT: ret void // void test_svst1_ver_vnum_za64(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_in("za") { @@ -268,8 +320,10 @@ void test_svst1_ver_vnum_za64(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-C-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-C-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-C-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]]) +// CHECK-C-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-C-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-C-NEXT: tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[TMP4]]) // CHECK-C-NEXT: ret void // // CHECK-CXX-LABEL: define dso_local void @_Z25test_svst1_ver_vnum_za128ju10__SVBool_tPvl( @@ -279,8 +333,10 @@ void test_svst1_ver_vnum_za64(uint32_t slice_base, svbool_t pg, void *ptr, int64 // CHECK-CXX-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.aarch64.sme.cntsb() // CHECK-CXX-NEXT: [[MULVL:%.*]] = mul i64 [[TMP1]], [[VNUM]] // CHECK-CXX-NEXT: [[TMP2:%.*]] = getelementptr i8, ptr [[PTR]], i64 [[MULVL]] -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[SLICE_BASE]]) -// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[SLICE_BASE]]) +// CHECK-CXX-NEXT: [[TMP3:%.*]] = trunc i64 [[VNUM]] to i32 +// CHECK-CXX-NEXT: [[TMP4:%.*]] = add i32 [[SLICE_BASE]], [[TMP3]] +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[TMP2]], i32 0, i32 [[TMP4]]) +// CHECK-CXX-NEXT: tail call void @llvm.aarch64.sme.st1q.vert( [[TMP0]], ptr [[TMP2]], i32 15, i32 [[TMP4]]) // CHECK-CXX-NEXT: ret void // void test_svst1_ver_vnum_za128(uint32_t slice_base, svbool_t pg, void *ptr, int64_t vnum) __arm_streaming __arm_in("za") { diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_fp8_fdot.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_fp8_fdot.c new file mode 100644 index 0000000000000..a151d162e0108 --- /dev/null +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_fp8_fdot.c @@ -0,0 +1,256 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// REQUIRES: aarch64-registered-target + +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sme -target-feature +sme2 -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sme -target-feature +sme2 -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -target-feature +sme-f8f16 -target-feature +sme-f8f32 -target-feature -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +#include + +#ifdef SVE_OVERLOADED_FORMS +#define SVE_ACLE_FUNC(A1,A2_UNUSED,A3,A4_UNUSED,A5) A1##A3##A5 +#else +#define SVE_ACLE_FUNC(A1,A2,A3,A4,A5) A1##A2##A3##A4##A5 +#endif + +// CHECK-LABEL: define dso_local void @test_svdot_lane_za32_f8_vg1x2( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.lane.za32.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z29test_svdot_lane_za32_f8_vg1x2j13svmfloat8x2_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0:[0-9]+]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.lane.za32.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_f8_vg1x2(uint32_t slice, svmfloat8x2_t zn, + svmfloat8_t zm, fpm_t fpmr) + __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svdot_lane_za32,_mf8,_vg1x2_fpm,,)(slice, zn, zm, 3, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svdot_lane_za32_f8_vg1x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.lane.za32.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z29test_svdot_lane_za32_f8_vg1x4j13svmfloat8x4_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.lane.za32.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za32_f8_vg1x4(uint32_t slice, svmfloat8x4_t zn, + svmfloat8_t zm, fpm_t fpmr) + __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svdot_lane_za32,_mf8,_vg1x4_fpm,,)(slice, zn, zm, 3, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svdot_lane_za16_f8_vg1x2( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.lane.za16.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z29test_svdot_lane_za16_f8_vg1x2j13svmfloat8x2_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.lane.za16.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za16_f8_vg1x2(uint32_t slice, svmfloat8x2_t zn, + svmfloat8_t zm, fpm_t fpmr) + __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svdot_lane_za16,_mf8,_vg1x2_fpm,,)(slice, zn, zm, 3, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svdot_lane_za16_f8_vg1x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.lane.za16.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z29test_svdot_lane_za16_f8_vg1x4j13svmfloat8x4_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.lane.za16.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_lane_za16_f8_vg1x4(uint32_t slice, svmfloat8x4_t zn, + svmfloat8_t zm, fpm_t fpmr) + __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svdot_lane_za16,_mf8,_vg1x4_fpm,,)(slice, zn, zm, 3, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svdot_single_za32_f8_vg1x2( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.single.za32.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z31test_svdot_single_za32_f8_vg1x2j13svmfloat8x2_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.single.za32.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_f8_vg1x2(uint32_t slice, svmfloat8x2_t zn, + svmfloat8_t zm, fpm_t fpmr) + __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svdot,_single,_za32,_mf8,_vg1x2_fpm)(slice, zn, zm, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svdot_single_za32_f8_vg1x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.single.za32.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z31test_svdot_single_za32_f8_vg1x4j13svmfloat8x4_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.single.za32.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za32_f8_vg1x4(uint32_t slice, svmfloat8x4_t zn, + svmfloat8_t zm, fpm_t fpmr) + __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svdot,_single,_za32,_mf8,_vg1x4_fpm)(slice, zn, zm, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svdot_multi_za32_f8_vg1x2( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM_COERCE0:%.*]], [[ZM_COERCE1:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.multi.za32.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM_COERCE0]], [[ZM_COERCE1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z30test_svdot_multi_za32_f8_vg1x2j13svmfloat8x2_tS_m( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM_COERCE0:%.*]], [[ZM_COERCE1:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.multi.za32.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM_COERCE0]], [[ZM_COERCE1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_f8_vg1x2(uint32_t slice, svmfloat8x2_t zn, + svmfloat8x2_t zm, fpm_t fpmr) + __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svdot,,_za32,_mf8,_vg1x2_fpm) (slice, zn, zm, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svdot_multi_za32_f8_vg1x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM_COERCE0:%.*]], [[ZM_COERCE1:%.*]], [[ZM_COERCE2:%.*]], [[ZM_COERCE3:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.multi.za32.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM_COERCE0]], [[ZM_COERCE1]], [[ZM_COERCE2]], [[ZM_COERCE3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z30test_svdot_multi_za32_f8_vg1x4j13svmfloat8x4_tS_m( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM_COERCE0:%.*]], [[ZM_COERCE1:%.*]], [[ZM_COERCE2:%.*]], [[ZM_COERCE3:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.multi.za32.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM_COERCE0]], [[ZM_COERCE1]], [[ZM_COERCE2]], [[ZM_COERCE3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za32_f8_vg1x4(uint32_t slice, svmfloat8x4_t zn, + svmfloat8x4_t zm, fpm_t fpmr) + __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svdot,,_za32,_mf8,_vg1x4_fpm)(slice, zn, zm, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svdot_single_za16_f8_vg1x2( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.single.za16.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z31test_svdot_single_za16_f8_vg1x2j13svmfloat8x2_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.single.za16.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za16_f8_vg1x2(uint32_t slice, svmfloat8x2_t zn, + svmfloat8_t zm, fpm_t fpmr) + __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svdot,_single,_za16,_mf8,_vg1x2_fpm)(slice, zn, zm, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svdot_single_za16_f8_vg1x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.single.za16.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z31test_svdot_single_za16_f8_vg1x4j13svmfloat8x4_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.single.za16.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_single_za16_f8_vg1x4(uint32_t slice, svmfloat8x4_t zn, + svmfloat8_t zm, fpm_t fpmr) + __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svdot,_single,_za16,_mf8,_vg1x4_fpm)(slice, zn, zm, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svdot_multi_za16_f8_vg1x2( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM_COERCE0:%.*]], [[ZM_COERCE1:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.multi.za16.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM_COERCE0]], [[ZM_COERCE1]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z30test_svdot_multi_za16_f8_vg1x2j13svmfloat8x2_tS_m( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM_COERCE0:%.*]], [[ZM_COERCE1:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.multi.za16.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM_COERCE0]], [[ZM_COERCE1]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za16_f8_vg1x2(uint32_t slice, svmfloat8x2_t zn, + svmfloat8x2_t zm, fpm_t fpmr) + __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svdot,,_za16,_mf8,_vg1x2_fpm) (slice, zn, zm, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svdot_multi_za16_f8_vg1x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM_COERCE0:%.*]], [[ZM_COERCE1:%.*]], [[ZM_COERCE2:%.*]], [[ZM_COERCE3:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.multi.za16.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM_COERCE0]], [[ZM_COERCE1]], [[ZM_COERCE2]], [[ZM_COERCE3]]) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z30test_svdot_multi_za16_f8_vg1x4j13svmfloat8x4_tS_m( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZN_COERCE2:%.*]], [[ZN_COERCE3:%.*]], [[ZM_COERCE0:%.*]], [[ZM_COERCE1:%.*]], [[ZM_COERCE2:%.*]], [[ZM_COERCE3:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: [[ENTRY:.*:]] +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fdot.multi.za16.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZN_COERCE2]], [[ZN_COERCE3]], [[ZM_COERCE0]], [[ZM_COERCE1]], [[ZM_COERCE2]], [[ZM_COERCE3]]) +// CPP-CHECK-NEXT: ret void +// +void test_svdot_multi_za16_f8_vg1x4(uint32_t slice, svmfloat8x4_t zn, + svmfloat8x4_t zm, fpm_t fpmr) + __arm_streaming __arm_inout("za") { + SVE_ACLE_FUNC(svdot,,_za16,_mf8,_vg1x4_fpm)(slice, zn, zm, fpmr); +} diff --git a/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_fp8_fvdot.c b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_fp8_fvdot.c new file mode 100644 index 0000000000000..fc95cf541172a --- /dev/null +++ b/clang/test/CodeGen/AArch64/sme2-intrinsics/acle_sme2_fp8_fvdot.c @@ -0,0 +1,80 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 4 + +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sme -target-feature +sme2 -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - %s | opt -S -passes mem2reg,instcombine,tailcallelim | FileCheck %s +// RUN: %clang_cc1 -DSVE_OVERLOADED_FORMS -triple aarch64 -target-feature +sme -target-feature +sme2 -target-feature +sme-f8f16 -target-feature +sme-f8f32 -disable-O0-optnone -Werror -Wall -emit-llvm -o - -x c++ %s | opt -S -passes mem2reg,instcombine,tailcallelim | FileCheck %s -check-prefix=CPP-CHECK +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -target-feature +sme-f8f16 -target-feature +sme-f8f32 -target-feature -S -disable-O0-optnone -Werror -Wall -o /dev/null %s + +// REQUIRES: aarch64-registered-target + +#include + +#ifdef SVE_OVERLOADED_FORMS +#define SVE_ACLE_FUNC(A1, A2_UNUSED, A3) A1##A3 +#else +#define SVE_ACLE_FUNC(A1, A2, A3) A1##A2##A3 +#endif + +// CHECK-LABEL: define dso_local void @test_svvdot_lane_za16_mf8_vg1x2( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fvdot.lane.za16.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 7) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z31test_svvdot_lane_za16_mf8_vg1x2j13svmfloat8x2_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0:[0-9]+]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fvdot.lane.za16.vg1x2(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 7) +// CPP-CHECK-NEXT: ret void +// +void test_svvdot_lane_za16_mf8_vg1x2(uint32_t slice, svmfloat8x2_t zn, + svmfloat8_t zm, + fpm_t fpmr) __arm_streaming + __arm_inout("za") { + SVE_ACLE_FUNC(svvdot_lane_za16, _mf8, _vg1x2_fpm)(slice, zn, zm, 7, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svvdotb_lane_za32_mf8_vg1x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fvdotb.lane.za32.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z32test_svvdotb_lane_za32_mf8_vg1x4j13svmfloat8x2_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fvdotb.lane.za32.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svvdotb_lane_za32_mf8_vg1x4(uint32_t slice, svmfloat8x2_t zn, + svmfloat8_t zm, + fpm_t fpmr) __arm_streaming + __arm_inout("za") { + SVE_ACLE_FUNC(svvdotb_lane_za32, _mf8, _vg1x4_fpm)(slice, zn, zm, 3, fpmr); +} + +// CHECK-LABEL: define dso_local void @test_svvdott_lane_za32_mf8_vg1x4( +// CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fvdott.lane.za32.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 3) +// CHECK-NEXT: ret void +// +// CPP-CHECK-LABEL: define dso_local void @_Z32test_svvdott_lane_za32_mf8_vg1x4j13svmfloat8x2_tu13__SVMfloat8_tm( +// CPP-CHECK-SAME: i32 noundef [[SLICE:%.*]], [[ZN_COERCE0:%.*]], [[ZN_COERCE1:%.*]], [[ZM:%.*]], i64 noundef [[FPMR:%.*]]) #[[ATTR0]] { +// CPP-CHECK-NEXT: entry: +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.set.fpmr(i64 [[FPMR]]) +// CPP-CHECK-NEXT: tail call void @llvm.aarch64.sme.fp8.fvdott.lane.za32.vg1x4(i32 [[SLICE]], [[ZN_COERCE0]], [[ZN_COERCE1]], [[ZM]], i32 3) +// CPP-CHECK-NEXT: ret void +// +void test_svvdott_lane_za32_mf8_vg1x4(uint32_t slice, svmfloat8x2_t zn, + svmfloat8_t zm, + fpm_t fpmr) __arm_streaming + __arm_inout("za") { + SVE_ACLE_FUNC(svvdott_lane_za32, _mf8, _vg1x4_fpm)(slice, zn, zm, 3, fpmr); +} diff --git a/clang/test/CodeGen/AArch64/sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c b/clang/test/CodeGen/AArch64/sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c index 54e90223a31de..28d69d52c9ae7 100644 --- a/clang/test/CodeGen/AArch64/sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c +++ b/clang/test/CodeGen/AArch64/sve-acle-__ARM_FEATURE_SVE_VECTOR_OPERATORS.c @@ -53,7 +53,7 @@ typedef int8_t vec_int8 __attribute__((vector_size(N / 8))); // CHECK128-LABEL: define{{.*}} <16 x i8> @f2(<16 x i8> noundef %x) // CHECK128-NEXT: entry: // CHECK128-NEXT: [[TMP0:%.*]] = tail call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) -// CHECK128-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv16i8.v16i8( undef, <16 x i8> [[X:%.*]], i64 0) +// CHECK128-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv16i8.v16i8( poison, <16 x i8> [[X:%.*]], i64 0) // CHECK128-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.asrd.nxv16i8( [[TMP0]], [[CASTSCALABLESVE]], i32 1) // CHECK128-NEXT: [[CASTFIXEDSVE:%.*]] = tail call <16 x i8> @llvm.vector.extract.v16i8.nxv16i8( [[TMP1]], i64 0) // CHECK128-NEXT: ret <16 x i8> [[CASTFIXEDSVE]] @@ -63,7 +63,7 @@ typedef int8_t vec_int8 __attribute__((vector_size(N / 8))); // CHECK-NEXT: entry: // CHECK-NEXT: [[X:%.*]] = load <[[#div(VBITS,8)]] x i8>, ptr [[TMP0:%.*]], align 16, [[TBAA6:!tbaa !.*]] // CHECK-NEXT: [[TMP1:%.*]] = tail call @llvm.aarch64.sve.ptrue.nxv16i1(i32 31) -// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv16i8.v[[#div(VBITS,8)]]i8( undef, <[[#div(VBITS,8)]] x i8> [[X]], i64 0) +// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv16i8.v[[#div(VBITS,8)]]i8( poison, <[[#div(VBITS,8)]] x i8> [[X]], i64 0) // CHECK-NEXT: [[TMP2:%.*]] = tail call @llvm.aarch64.sve.asrd.nxv16i8( [[TMP1]], [[CASTSCALABLESVE]], i32 1) // CHECK-NEXT: [[CASTFIXEDSVE:%.*]] = tail call <[[#div(VBITS,8)]] x i8> @llvm.vector.extract.v[[#div(VBITS,8)]]i8.nxv16i8( [[TMP2]], i64 0) // CHECK-NEXT: store <[[#div(VBITS,8)]] x i8> [[CASTFIXEDSVE]], ptr [[AGG_RESULT:%.*]], align 16, [[TBAA6]] diff --git a/clang/test/CodeGen/PowerPC/builtins-ppc-pair-mma.c b/clang/test/CodeGen/PowerPC/builtins-ppc-pair-mma.c index 5422d993ff157..08ff936a0a797 100644 --- a/clang/test/CodeGen/PowerPC/builtins-ppc-pair-mma.c +++ b/clang/test/CodeGen/PowerPC/builtins-ppc-pair-mma.c @@ -25,13 +25,13 @@ void test1(unsigned char *vqp, unsigned char *vpp, vector unsigned char vc, unsi // CHECK-NEXT: [[TMP2:%.*]] = extractvalue { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } [[TMP1]], 0 // CHECK-NEXT: store <16 x i8> [[TMP2]], ptr [[RESP:%.*]], align 16 // CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } [[TMP1]], 1 -// CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[RESP]], i64 16 +// CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw i8, ptr [[RESP]], i64 16 // CHECK-NEXT: store <16 x i8> [[TMP3]], ptr [[TMP4]], align 16 // CHECK-NEXT: [[TMP5:%.*]] = extractvalue { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } [[TMP1]], 2 -// CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i8, ptr [[RESP]], i64 32 +// CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw i8, ptr [[RESP]], i64 32 // CHECK-NEXT: store <16 x i8> [[TMP5]], ptr [[TMP6]], align 16 // CHECK-NEXT: [[TMP7:%.*]] = extractvalue { <16 x i8>, <16 x i8>, <16 x i8>, <16 x i8> } [[TMP1]], 3 -// CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds i8, ptr [[RESP]], i64 48 +// CHECK-NEXT: [[TMP8:%.*]] = getelementptr inbounds nuw i8, ptr [[RESP]], i64 48 // CHECK-NEXT: store <16 x i8> [[TMP7]], ptr [[TMP8]], align 16 // CHECK-NEXT: ret void // @@ -60,7 +60,7 @@ void test3(unsigned char *vqp, unsigned char *vpp, vector unsigned char vc, unsi // CHECK-NEXT: [[TMP2:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[TMP1]], 0 // CHECK-NEXT: store <16 x i8> [[TMP2]], ptr [[RESP:%.*]], align 16 // CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[TMP1]], 1 -// CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[RESP]], i64 16 +// CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw i8, ptr [[RESP]], i64 16 // CHECK-NEXT: store <16 x i8> [[TMP3]], ptr [[TMP4]], align 16 // CHECK-NEXT: ret void // @@ -1072,7 +1072,7 @@ void test76(unsigned char *vqp, unsigned char *vpp, vector unsigned char vc, uns // CHECK-NEXT: [[TMP2:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[TMP1]], 0 // CHECK-NEXT: store <16 x i8> [[TMP2]], ptr [[RESP:%.*]], align 16 // CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <16 x i8>, <16 x i8> } [[TMP1]], 1 -// CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds i8, ptr [[RESP]], i64 16 +// CHECK-NEXT: [[TMP4:%.*]] = getelementptr inbounds nuw i8, ptr [[RESP]], i64 16 // CHECK-NEXT: store <16 x i8> [[TMP3]], ptr [[TMP4]], align 16 // CHECK-NEXT: ret void // diff --git a/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-bitcast.c b/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-bitcast.c index e684513bb1442..ecde52eb3d762 100644 --- a/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-bitcast.c +++ b/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-bitcast.c @@ -71,21 +71,21 @@ DEFINE_STRUCT(bool64) // CHECK-64-NEXT: entry: // CHECK-64-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 8 // CHECK-64-NEXT: [[TMP0:%.*]] = load <1 x i64>, ptr [[Y]], align 8, !tbaa [[TBAA6:![0-9]+]] -// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v1i64( undef, <1 x i64> [[TMP0]], i64 0) +// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v1i64( poison, <1 x i64> [[TMP0]], i64 0) // CHECK-64-NEXT: ret [[CAST_SCALABLE]] // // CHECK-128-LABEL: @read_int64m1( // CHECK-128-NEXT: entry: // CHECK-128-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 16 // CHECK-128-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[Y]], align 8, !tbaa [[TBAA6:![0-9]+]] -// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v2i64( undef, <2 x i64> [[TMP0]], i64 0) +// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v2i64( poison, <2 x i64> [[TMP0]], i64 0) // CHECK-128-NEXT: ret [[CAST_SCALABLE]] // // CHECK-256-LABEL: @read_int64m1( // CHECK-256-NEXT: entry: // CHECK-256-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 32 // CHECK-256-NEXT: [[TMP0:%.*]] = load <4 x i64>, ptr [[Y]], align 8, !tbaa [[TBAA6:![0-9]+]] -// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v4i64( undef, <4 x i64> [[TMP0]], i64 0) +// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v4i64( poison, <4 x i64> [[TMP0]], i64 0) // CHECK-256-NEXT: ret [[CAST_SCALABLE]] // vint64m1_t read_int64m1(struct struct_int64m1 *s) { @@ -125,21 +125,21 @@ void write_int64m1(struct struct_int64m1 *s, vint64m1_t x) { // CHECK-64-NEXT: entry: // CHECK-64-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 8 // CHECK-64-NEXT: [[TMP0:%.*]] = load <1 x double>, ptr [[Y]], align 8, !tbaa [[TBAA6]] -// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1f64.v1f64( undef, <1 x double> [[TMP0]], i64 0) +// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1f64.v1f64( poison, <1 x double> [[TMP0]], i64 0) // CHECK-64-NEXT: ret [[CAST_SCALABLE]] // // CHECK-128-LABEL: @read_float64m1( // CHECK-128-NEXT: entry: // CHECK-128-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 16 // CHECK-128-NEXT: [[TMP0:%.*]] = load <2 x double>, ptr [[Y]], align 8, !tbaa [[TBAA6]] -// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1f64.v2f64( undef, <2 x double> [[TMP0]], i64 0) +// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1f64.v2f64( poison, <2 x double> [[TMP0]], i64 0) // CHECK-128-NEXT: ret [[CAST_SCALABLE]] // // CHECK-256-LABEL: @read_float64m1( // CHECK-256-NEXT: entry: // CHECK-256-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 32 // CHECK-256-NEXT: [[TMP0:%.*]] = load <4 x double>, ptr [[Y]], align 8, !tbaa [[TBAA6]] -// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1f64.v4f64( undef, <4 x double> [[TMP0]], i64 0) +// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1f64.v4f64( poison, <4 x double> [[TMP0]], i64 0) // CHECK-256-NEXT: ret [[CAST_SCALABLE]] // vfloat64m1_t read_float64m1(struct struct_float64m1 *s) { @@ -179,7 +179,7 @@ void write_float64m1(struct struct_float64m1 *s, vfloat64m1_t x) { // CHECK-64-NEXT: entry: // CHECK-64-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 8 // CHECK-64-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[Y]], align 8, !tbaa [[TBAA6]] -// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8i8.v8i8( undef, <8 x i8> [[TMP0]], i64 0) +// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8i8.v8i8( poison, <8 x i8> [[TMP0]], i64 0) // CHECK-64-NEXT: [[TMP1:%.*]] = bitcast [[CAST_SCALABLE]] to // CHECK-64-NEXT: ret [[TMP1]] // @@ -187,7 +187,7 @@ void write_float64m1(struct struct_float64m1 *s, vfloat64m1_t x) { // CHECK-128-NEXT: entry: // CHECK-128-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 16 // CHECK-128-NEXT: [[TMP0:%.*]] = load <16 x i8>, ptr [[Y]], align 8, !tbaa [[TBAA6]] -// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8i8.v16i8( undef, <16 x i8> [[TMP0]], i64 0) +// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8i8.v16i8( poison, <16 x i8> [[TMP0]], i64 0) // CHECK-128-NEXT: [[TMP1:%.*]] = bitcast [[CAST_SCALABLE]] to // CHECK-128-NEXT: ret [[TMP1]] // @@ -195,7 +195,7 @@ void write_float64m1(struct struct_float64m1 *s, vfloat64m1_t x) { // CHECK-256-NEXT: entry: // CHECK-256-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 32 // CHECK-256-NEXT: [[TMP0:%.*]] = load <32 x i8>, ptr [[Y]], align 8, !tbaa [[TBAA6]] -// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8i8.v32i8( undef, <32 x i8> [[TMP0]], i64 0) +// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8i8.v32i8( poison, <32 x i8> [[TMP0]], i64 0) // CHECK-256-NEXT: [[TMP1:%.*]] = bitcast [[CAST_SCALABLE]] to // CHECK-256-NEXT: ret [[TMP1]] // diff --git a/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-cast.c b/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-cast.c index 3fa104b78f212..7992951346d54 100644 --- a/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-cast.c +++ b/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-cast.c @@ -120,7 +120,7 @@ vbool32_t to_vbool32_t(fixed_bool32_t type) { // CHECK-LABEL: @to_vint32m1_t__from_gnu_int32m1_t( // CHECK-NEXT: entry: // CHECK-NEXT: [[TYPE:%.*]] = load <8 x i32>, ptr [[TMP0:%.*]], align 32, !tbaa [[TBAA8]] -// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i32.v8i32( undef, <8 x i32> [[TYPE]], i64 0) +// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i32.v8i32( poison, <8 x i32> [[TYPE]], i64 0) // CHECK-NEXT: ret [[CAST_SCALABLE]] // vint32m1_t to_vint32m1_t__from_gnu_int32m1_t(gnu_int32m1_t type) { diff --git a/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-codegen.c b/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-codegen.c index bfdb39b6ac82d..d81855aea2e5e 100644 --- a/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-codegen.c +++ b/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-codegen.c @@ -57,14 +57,14 @@ fixed_bool32_t global_bool32; // CHECK-NEXT: store [[VEC:%.*]], ptr [[VEC_ADDR]], align 1 // CHECK-NEXT: [[TMP0:%.*]] = load , ptr [[M_ADDR]], align 1 // CHECK-NEXT: [[TMP1:%.*]] = load <32 x i8>, ptr @global_bool1, align 8 -// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call @llvm.vector.insert.nxv8i8.v32i8( undef, <32 x i8> [[TMP1]], i64 0) +// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call @llvm.vector.insert.nxv8i8.v32i8( poison, <32 x i8> [[TMP1]], i64 0) // CHECK-NEXT: [[TMP2:%.*]] = bitcast [[CAST_SCALABLE]] to // CHECK-NEXT: [[TMP3:%.*]] = call @llvm.riscv.vmand.nxv64i1.i64( [[TMP0]], [[TMP2]], i64 256) // CHECK-NEXT: store [[TMP3]], ptr [[MASK]], align 1 // CHECK-NEXT: [[TMP4:%.*]] = load , ptr [[MASK]], align 1 // CHECK-NEXT: [[TMP5:%.*]] = load , ptr [[VEC_ADDR]], align 1 // CHECK-NEXT: [[TMP6:%.*]] = load <256 x i8>, ptr @global_vec_int8m8, align 8 -// CHECK-NEXT: [[CAST_SCALABLE1:%.*]] = call @llvm.vector.insert.nxv64i8.v256i8( undef, <256 x i8> [[TMP6]], i64 0) +// CHECK-NEXT: [[CAST_SCALABLE1:%.*]] = call @llvm.vector.insert.nxv64i8.v256i8( poison, <256 x i8> [[TMP6]], i64 0) // CHECK-NEXT: [[TMP7:%.*]] = call @llvm.riscv.vadd.mask.nxv64i8.nxv64i8.i64( poison, [[TMP5]], [[CAST_SCALABLE1]], [[TMP4]], i64 256, i64 3) // CHECK-NEXT: [[CAST_FIXED:%.*]] = call <256 x i8> @llvm.vector.extract.v256i8.nxv64i8( [[TMP7]], i64 0) // CHECK-NEXT: store <256 x i8> [[CAST_FIXED]], ptr [[RETVAL]], align 8 @@ -87,14 +87,14 @@ fixed_int8m8_t test_bool1(vbool1_t m, vint8m8_t vec) { // CHECK-NEXT: store [[VEC:%.*]], ptr [[VEC_ADDR]], align 2 // CHECK-NEXT: [[TMP0:%.*]] = load , ptr [[M_ADDR]], align 1 // CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr @global_bool4, align 8 -// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call @llvm.vector.insert.nxv2i8.v8i8( undef, <8 x i8> [[TMP1]], i64 0) +// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call @llvm.vector.insert.nxv2i8.v8i8( poison, <8 x i8> [[TMP1]], i64 0) // CHECK-NEXT: [[TMP2:%.*]] = bitcast [[CAST_SCALABLE]] to // CHECK-NEXT: [[TMP3:%.*]] = call @llvm.riscv.vmand.nxv16i1.i64( [[TMP0]], [[TMP2]], i64 64) // CHECK-NEXT: store [[TMP3]], ptr [[MASK]], align 1 // CHECK-NEXT: [[TMP4:%.*]] = load , ptr [[MASK]], align 1 // CHECK-NEXT: [[TMP5:%.*]] = load , ptr [[VEC_ADDR]], align 2 // CHECK-NEXT: [[TMP6:%.*]] = load <64 x i16>, ptr @global_vec_int16m4, align 8 -// CHECK-NEXT: [[CAST_SCALABLE1:%.*]] = call @llvm.vector.insert.nxv16i16.v64i16( undef, <64 x i16> [[TMP6]], i64 0) +// CHECK-NEXT: [[CAST_SCALABLE1:%.*]] = call @llvm.vector.insert.nxv16i16.v64i16( poison, <64 x i16> [[TMP6]], i64 0) // CHECK-NEXT: [[TMP7:%.*]] = call @llvm.riscv.vadd.mask.nxv16i16.nxv16i16.i64( poison, [[TMP5]], [[CAST_SCALABLE1]], [[TMP4]], i64 64, i64 3) // CHECK-NEXT: [[CAST_FIXED:%.*]] = call <64 x i16> @llvm.vector.extract.v64i16.nxv16i16( [[TMP7]], i64 0) // CHECK-NEXT: store <64 x i16> [[CAST_FIXED]], ptr [[RETVAL]], align 8 @@ -125,7 +125,7 @@ fixed_int16m4_t test_bool4(vbool4_t m, vint16m4_t vec) { // CHECK-NEXT: [[TMP4:%.*]] = load , ptr [[MASK]], align 1 // CHECK-NEXT: [[TMP5:%.*]] = load , ptr [[VEC_ADDR]], align 4 // CHECK-NEXT: [[TMP6:%.*]] = load <8 x i32>, ptr @global_vec, align 8 -// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call @llvm.vector.insert.nxv2i32.v8i32( undef, <8 x i32> [[TMP6]], i64 0) +// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call @llvm.vector.insert.nxv2i32.v8i32( poison, <8 x i32> [[TMP6]], i64 0) // CHECK-NEXT: [[TMP7:%.*]] = call @llvm.riscv.vadd.mask.nxv2i32.nxv2i32.i64( poison, [[TMP5]], [[CAST_SCALABLE]], [[TMP4]], i64 8, i64 3) // CHECK-NEXT: [[CAST_FIXED:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32( [[TMP7]], i64 0) // CHECK-NEXT: store <8 x i32> [[CAST_FIXED]], ptr [[RETVAL]], align 8 @@ -247,7 +247,7 @@ fixed_bool32_t address_of_array_idx_bool32() { // CHECK-NEXT: [[VEC_ADDR:%.*]] = alloca , align 4 // CHECK-NEXT: store [[VEC:%.*]], ptr [[VEC_ADDR]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load <8 x i32>, ptr @global_vec, align 8 -// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call @llvm.vector.insert.nxv2i32.v8i32( undef, <8 x i32> [[TMP0]], i64 0) +// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call @llvm.vector.insert.nxv2i32.v8i32( poison, <8 x i32> [[TMP0]], i64 0) // CHECK-NEXT: [[TMP1:%.*]] = load , ptr [[VEC_ADDR]], align 4 // CHECK-NEXT: [[TMP2:%.*]] = call @llvm.riscv.vadd.nxv2i32.nxv2i32.i64( poison, [[CAST_SCALABLE]], [[TMP1]], i64 8) // CHECK-NEXT: [[CAST_FIXED:%.*]] = call <8 x i32> @llvm.vector.extract.v8i32.nxv2i32( [[TMP2]], i64 0) @@ -303,7 +303,7 @@ fixed_int32m2_t array_arg_m2(fixed_int32m2_t arr[]) { // CHECK-NEXT: [[VEC_ADDR:%.*]] = alloca , align 4 // CHECK-NEXT: store [[VEC:%.*]], ptr [[VEC_ADDR]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = load <16 x i32>, ptr @global_vec_m2, align 8 -// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call @llvm.vector.insert.nxv4i32.v16i32( undef, <16 x i32> [[TMP0]], i64 0) +// CHECK-NEXT: [[CAST_SCALABLE:%.*]] = call @llvm.vector.insert.nxv4i32.v16i32( poison, <16 x i32> [[TMP0]], i64 0) // CHECK-NEXT: [[TMP1:%.*]] = load , ptr [[VEC_ADDR]], align 4 // CHECK-NEXT: [[TMP2:%.*]] = call @llvm.riscv.vadd.nxv4i32.nxv4i32.i64( poison, [[CAST_SCALABLE]], [[TMP1]], i64 16) // CHECK-NEXT: [[CAST_FIXED:%.*]] = call <16 x i32> @llvm.vector.extract.v16i32.nxv4i32( [[TMP2]], i64 0) diff --git a/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-globals.c b/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-globals.c index 663e436b4dab6..4bd6311e05b03 100644 --- a/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-globals.c +++ b/clang/test/CodeGen/RISCV/attr-rvv-vector-bits-globals.c @@ -105,13 +105,13 @@ void write_global_bool32(vbool32_t v) { global_bool32 = v; } // CHECK-64-LABEL: @read_global_i64( // CHECK-64-NEXT: entry: // CHECK-64-NEXT: [[TMP0:%.*]] = load <1 x i64>, ptr @global_i64, align 8, !tbaa [[TBAA6]] -// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v1i64( undef, <1 x i64> [[TMP0]], i64 0) +// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v1i64( poison, <1 x i64> [[TMP0]], i64 0) // CHECK-64-NEXT: ret [[CAST_SCALABLE]] // // CHECK-256-LABEL: @read_global_i64( // CHECK-256-NEXT: entry: // CHECK-256-NEXT: [[TMP0:%.*]] = load <4 x i64>, ptr @global_i64, align 8, !tbaa [[TBAA6]] -// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v4i64( undef, <4 x i64> [[TMP0]], i64 0) +// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv1i64.v4i64( poison, <4 x i64> [[TMP0]], i64 0) // CHECK-256-NEXT: ret [[CAST_SCALABLE]] // vint64m1_t read_global_i64() { return global_i64; } @@ -119,14 +119,14 @@ vint64m1_t read_global_i64() { return global_i64; } // CHECK-64-LABEL: @read_global_bool1( // CHECK-64-NEXT: entry: // CHECK-64-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr @global_bool1, align 8, !tbaa [[TBAA6]] -// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8i8.v8i8( undef, <8 x i8> [[TMP0]], i64 0) +// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8i8.v8i8( poison, <8 x i8> [[TMP0]], i64 0) // CHECK-64-NEXT: [[TMP1:%.*]] = bitcast [[CAST_SCALABLE]] to // CHECK-64-NEXT: ret [[TMP1]] // // CHECK-256-LABEL: @read_global_bool1( // CHECK-256-NEXT: entry: // CHECK-256-NEXT: [[TMP0:%.*]] = load <32 x i8>, ptr @global_bool1, align 8, !tbaa [[TBAA6]] -// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8i8.v32i8( undef, <32 x i8> [[TMP0]], i64 0) +// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8i8.v32i8( poison, <32 x i8> [[TMP0]], i64 0) // CHECK-256-NEXT: [[TMP1:%.*]] = bitcast [[CAST_SCALABLE]] to // CHECK-256-NEXT: ret [[TMP1]] // @@ -135,14 +135,14 @@ vbool1_t read_global_bool1() { return global_bool1; } // CHECK-64-LABEL: @read_global_bool4( // CHECK-64-NEXT: entry: // CHECK-64-NEXT: [[TMP0:%.*]] = load <2 x i8>, ptr @global_bool4, align 2, !tbaa [[TBAA6]] -// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v2i8( undef, <2 x i8> [[TMP0]], i64 0) +// CHECK-64-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v2i8( poison, <2 x i8> [[TMP0]], i64 0) // CHECK-64-NEXT: [[TMP1:%.*]] = bitcast [[CAST_SCALABLE]] to // CHECK-64-NEXT: ret [[TMP1]] // // CHECK-256-LABEL: @read_global_bool4( // CHECK-256-NEXT: entry: // CHECK-256-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr @global_bool4, align 8, !tbaa [[TBAA6]] -// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v8i8( undef, <8 x i8> [[TMP0]], i64 0) +// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v8i8( poison, <8 x i8> [[TMP0]], i64 0) // CHECK-256-NEXT: [[TMP1:%.*]] = bitcast [[CAST_SCALABLE]] to // CHECK-256-NEXT: ret [[TMP1]] // diff --git a/clang/test/CodeGen/RISCV/riscv-inline-asm.c b/clang/test/CodeGen/RISCV/riscv-inline-asm.c index de90e513ea1ff..9da306807ed0d 100644 --- a/clang/test/CodeGen/RISCV/riscv-inline-asm.c +++ b/clang/test/CodeGen/RISCV/riscv-inline-asm.c @@ -90,9 +90,9 @@ extern int var, arr[2][2]; struct Pair { int a, b; } pair; // CHECK-LABEL: test_s( -// CHECK: call void asm sideeffect "// $0 $1 $2", "s,s,s"(ptr nonnull @var, ptr nonnull getelementptr inbounds (i8, ptr @arr, {{.*}}), ptr nonnull @test_s) +// CHECK: call void asm sideeffect "// $0 $1 $2", "s,s,s"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s) // CHECK: call void asm sideeffect "// $0", "s"(ptr nonnull getelementptr inbounds nuw (i8, ptr @pair, {{.*}})) -// CHECK: call void asm sideeffect "// $0 $1 $2", "S,S,S"(ptr nonnull @var, ptr nonnull getelementptr inbounds (i8, ptr @arr, {{.*}}), ptr nonnull @test_s) +// CHECK: call void asm sideeffect "// $0 $1 $2", "S,S,S"(ptr nonnull @var, ptr nonnull getelementptr inbounds nuw (i8, ptr @arr, {{.*}}), ptr nonnull @test_s) void test_s(void) { asm("// %0 %1 %2" :: "s"(&var), "s"(&arr[1][1]), "s"(test_s)); asm("// %0" :: "s"(&pair.b)); diff --git a/clang/test/CodeGen/SystemZ/builtin-setjmp-logjmp.c b/clang/test/CodeGen/SystemZ/builtin-setjmp-logjmp.c new file mode 100644 index 0000000000000..898891fa182ea --- /dev/null +++ b/clang/test/CodeGen/SystemZ/builtin-setjmp-logjmp.c @@ -0,0 +1,26 @@ +// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 +// RUN: %clang_cc1 -triple s390x-linux -emit-llvm -o - %s | FileCheck %s + +void *buf[20]; + +// CHECK-LABEL: define dso_local void @foo( +// CHECK-SAME: ) #[[ATTR0:[0-9]+]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: [[TMP0:%.*]] = call i32 @llvm.eh.sjlj.setjmp(ptr @buf) +// CHECK-NEXT: ret void +// +void foo() +{ + __builtin_setjmp (buf); +} + +// CHECK-LABEL: define dso_local void @foo1( +// CHECK-SAME: ) #[[ATTR0]] { +// CHECK-NEXT: [[ENTRY:.*:]] +// CHECK-NEXT: call void @llvm.eh.sjlj.longjmp(ptr @buf) +// CHECK-NEXT: unreachable +// +void foo1() +{ + __builtin_longjmp (buf, 1); +} diff --git a/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-malloc.c b/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-malloc.c index 1b05e8aa5052a..c0ca3dab51258 100644 --- a/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-malloc.c +++ b/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes-malloc.c @@ -4,7 +4,7 @@ void *__malloc31(size_t); int test_1() { // X64-LABEL: define {{.*}} i32 @test_1() - // X64: ret i32 135 + // X64: ret i32 %add20 int *__ptr32 a; int *b; int i; diff --git a/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes.c b/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes.c index 82bb7a52d05d1..33cf0ddb47236 100644 --- a/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes.c +++ b/clang/test/CodeGen/SystemZ/zos-mixed-ptr-sizes.c @@ -48,21 +48,21 @@ void test_indexing(struct Foo *f) { void test_indexing_2(struct Foo *f) { // X64-LABEL: define void @test_indexing_2(ptr noundef initializes((16, 24)) %f) - // X64: getelementptr inbounds i8, ptr addrspace(1) {{%[0-9]}}, i32 16 - // X64: getelementptr inbounds i8, ptr {{%[0-9]}}, i64 24 + // X64: getelementptr inbounds nuw i8, ptr addrspace(1) {{%[0-9]}}, i32 16 + // X64: getelementptr inbounds nuw i8, ptr {{%[0-9]}}, i64 24 f->cp64 = ((char *** __ptr32 *)1028)[1][2][3]; use_foo(f); } unsigned long* test_misc() { // X64-LABEL: define ptr @test_misc() - // X64: %arrayidx = getelementptr inbounds i8, ptr addrspace(1) %0, i32 88 + // X64: %arrayidx = getelementptr inbounds nuw i8, ptr addrspace(1) %0, i32 88 // X64-NEXT: %1 = load ptr, ptr addrspace(1) %arrayidx - // X64-NEXT: %arrayidx1 = getelementptr inbounds i8, ptr %1, i64 8 + // X64-NEXT: %arrayidx1 = getelementptr inbounds nuw i8, ptr %1, i64 8 // X64-NEXT: %2 = load ptr, ptr %arrayidx1 - // X64-NEXT: %arrayidx2 = getelementptr inbounds i8, ptr %2, i64 904 + // X64-NEXT: %arrayidx2 = getelementptr inbounds nuw i8, ptr %2, i64 904 // X64-NEXT: %3 = load ptr, ptr %arrayidx2 - // X64-NEXT: %arrayidx3 = getelementptr inbounds i8, ptr %3, i64 1192 + // X64-NEXT: %arrayidx3 = getelementptr inbounds nuw i8, ptr %3, i64 1192 unsigned long* x = (unsigned long*)((char***** __ptr32*)1208)[0][11][1][113][149]; return x; } @@ -71,9 +71,9 @@ char* __ptr32* __ptr32 test_misc_2() { // X64-LABEL: define ptr addrspace(1) @test_misc_2() // X64: br i1 %cmp, label %if.then, label %if.end // X64: %1 = load ptr addrspace(1), ptr inttoptr (i64 16 to ptr) - // X64-NEXT: %arrayidx = getelementptr inbounds i8, ptr addrspace(1) %1, i32 544 + // X64-NEXT: %arrayidx = getelementptr inbounds nuw i8, ptr addrspace(1) %1, i32 544 // X64-NEXT: %2 = load ptr addrspace(1), ptr addrspace(1) %arrayidx - // X64-NEXT: %arrayidx1 = getelementptr inbounds i8, ptr addrspace(1) %2, i32 24 + // X64-NEXT: %arrayidx1 = getelementptr inbounds nuw i8, ptr addrspace(1) %2, i32 24 // X64-NEXT: %3 = load ptr addrspace(1), ptr addrspace(1) %arrayidx1 // X64-NEXT: store ptr addrspace(1) %3, ptr @test_misc_2.res // X64: ret ptr addrspace(1) @@ -88,7 +88,7 @@ unsigned short test_misc_3() { // X64-LABEL: define zeroext i16 @test_misc_3() // X64: %0 = load ptr addrspace(1), ptr inttoptr (i64 548 to ptr) // X64-NEXT: %1 = addrspacecast ptr addrspace(1) %0 to ptr - // X64-NEXT: %arrayidx = getelementptr inbounds i8, ptr %1, i64 36 + // X64-NEXT: %arrayidx = getelementptr inbounds nuw i8, ptr %1, i64 36 // X64-NEXT: %2 = load i16, ptr %arrayidx, align 2 // X64-NEXT: ret i16 %2 unsigned short this_asid = ((unsigned short*)(*(char* __ptr32*)(0x224)))[18]; @@ -97,10 +97,10 @@ unsigned short test_misc_3() { int test_misc_4() { // X64-LABEL: define signext range(i32 0, 2) i32 @test_misc_4() - // X64: getelementptr inbounds i8, ptr addrspace(1) {{%[0-9]}}, i32 88 - // X64: getelementptr inbounds i8, ptr {{%[0-9]}}, i64 8 - // X64: getelementptr inbounds i8, ptr {{%[0-9]}}, i64 984 - // X64: getelementptr inbounds i8, ptr %3, i64 80 + // X64: getelementptr inbounds nuw i8, ptr addrspace(1) {{%[0-9]}}, i32 88 + // X64: getelementptr inbounds nuw i8, ptr {{%[0-9]}}, i64 8 + // X64: getelementptr inbounds nuw i8, ptr {{%[0-9]}}, i64 984 + // X64: getelementptr inbounds nuw i8, ptr %3, i64 80 // X64: icmp sgt i32 {{.*[0-9]}}, 67240703 // X64: ret i32 int a = (*(int*)(80 + ((char**** __ptr32*)1208)[0][11][1][123]) > 0x040202FF); @@ -189,7 +189,7 @@ int test_function_ptr32_is_32bit() { int get_processor_count() { // X64-LABEL: define signext range(i32 -128, 128) i32 @get_processor_count() // X64: load ptr addrspace(1), ptr inttoptr (i64 16 to ptr) - // X64-NEXT: [[ARR_IDX1:%[a-z].*]] = getelementptr inbounds i8, ptr addrspace(1) %0, i32 660 + // X64-NEXT: [[ARR_IDX1:%[a-z].*]] = getelementptr inbounds nuw i8, ptr addrspace(1) %0, i32 660 // X64: load ptr addrspace(1), ptr addrspace(1) [[ARR_IDX1]] // X64: load i8, ptr addrspace(1) {{%[a-z].*}} // X64: sext i8 {{%[0-9]}} to i32 diff --git a/clang/test/CodeGen/allow-ubsan-check-inline.c b/clang/test/CodeGen/allow-ubsan-check-inline.c new file mode 100644 index 0000000000000..1de24ab90dac0 --- /dev/null +++ b/clang/test/CodeGen/allow-ubsan-check-inline.c @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow -mllvm -ubsan-guard-checks -O3 -mllvm -lower-allow-check-random-rate=1 -Rpass=lower-allow-check -Rpass-missed=lower-allow-check -fno-inline 2>&1 | FileCheck %s --check-prefixes=NOINL --implicit-check-not="remark:" +// RUN: %clang_cc1 -triple x86_64-pc-linux-gnu -emit-llvm -o - %s -fsanitize=signed-integer-overflow -mllvm -ubsan-guard-checks -O3 -mllvm -lower-allow-check-random-rate=1 -Rpass=lower-allow-check -Rpass-missed=lower-allow-check 2>&1 | FileCheck %s --check-prefixes=INLINE --implicit-check-not="remark:" + +int get(); +void set(int x); + +// We will only make decision in the `overflow` function. +// NOINL-COUNT-1: remark: Allowed check: + +// We will make decision on every inline. +// INLINE-COUNT-5: remark: Allowed check: + +static void overflow() { + set(get() + get()); +} + +void test() { + overflow(); + overflow(); + overflow(); + overflow(); + overflow(); +} diff --git a/clang/test/CodeGen/arm-mve-intrinsics/vadc.c b/clang/test/CodeGen/arm-mve-intrinsics/vadc.c index 21087b83300c8..29e067d65c6c8 100644 --- a/clang/test/CodeGen/arm-mve-intrinsics/vadc.c +++ b/clang/test/CodeGen/arm-mve-intrinsics/vadc.c @@ -92,7 +92,7 @@ int32x4_t test_vadcq_m_s32(int32x4_t inactive, int32x4_t a, int32x4_t b, unsigne // CHECK-LABEL: @test_vsbciq_s32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0) +// CHECK-NEXT: [[TMP0:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 536870912) // CHECK-NEXT: [[TMP1:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP0]], 1 // CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP1]], 29 // CHECK-NEXT: [[TMP3:%.*]] = and i32 1, [[TMP2]] @@ -110,7 +110,7 @@ int32x4_t test_vsbciq_s32(int32x4_t a, int32x4_t b, unsigned *carry_out) { // CHECK-LABEL: @test_vsbciq_u32( // CHECK-NEXT: entry: -// CHECK-NEXT: [[TMP0:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0) +// CHECK-NEXT: [[TMP0:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.v4i32(<4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 536870912) // CHECK-NEXT: [[TMP1:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP0]], 1 // CHECK-NEXT: [[TMP2:%.*]] = lshr i32 [[TMP1]], 29 // CHECK-NEXT: [[TMP3:%.*]] = and i32 1, [[TMP2]] @@ -170,7 +170,7 @@ uint32x4_t test_vsbcq_u32(uint32x4_t a, uint32x4_t b, unsigned *carry) { // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 // CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.predicated.v4i32.v4i1(<4 x i32> [[INACTIVE:%.*]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0, <4 x i1> [[TMP1]]) +// CHECK-NEXT: [[TMP2:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.predicated.v4i32.v4i1(<4 x i32> [[INACTIVE:%.*]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 536870912, <4 x i1> [[TMP1]]) // CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 1 // CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP3]], 29 // CHECK-NEXT: [[TMP5:%.*]] = and i32 1, [[TMP4]] @@ -190,7 +190,7 @@ int32x4_t test_vsbciq_m_s32(int32x4_t inactive, int32x4_t a, int32x4_t b, unsign // CHECK-NEXT: entry: // CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[P:%.*]] to i32 // CHECK-NEXT: [[TMP1:%.*]] = call <4 x i1> @llvm.arm.mve.pred.i2v.v4i1(i32 [[TMP0]]) -// CHECK-NEXT: [[TMP2:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.predicated.v4i32.v4i1(<4 x i32> [[INACTIVE:%.*]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 0, <4 x i1> [[TMP1]]) +// CHECK-NEXT: [[TMP2:%.*]] = call { <4 x i32>, i32 } @llvm.arm.mve.vsbc.predicated.v4i32.v4i1(<4 x i32> [[INACTIVE:%.*]], <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], i32 536870912, <4 x i1> [[TMP1]]) // CHECK-NEXT: [[TMP3:%.*]] = extractvalue { <4 x i32>, i32 } [[TMP2]], 1 // CHECK-NEXT: [[TMP4:%.*]] = lshr i32 [[TMP3]], 29 // CHECK-NEXT: [[TMP5:%.*]] = and i32 1, [[TMP4]] diff --git a/clang/test/CodeGen/arm64_32-vaarg.c b/clang/test/CodeGen/arm64_32-vaarg.c index 3f1f4443436da..72c23d4967d2d 100644 --- a/clang/test/CodeGen/arm64_32-vaarg.c +++ b/clang/test/CodeGen/arm64_32-vaarg.c @@ -10,7 +10,7 @@ typedef struct { int test_int(OneInt input, va_list *mylist) { // CHECK-LABEL: define{{.*}} i32 @test_int(i32 %input // CHECK: [[START:%.*]] = load ptr, ptr %mylist -// CHECK: [[NEXT:%.*]] = getelementptr inbounds i8, ptr [[START]], i32 4 +// CHECK: [[NEXT:%.*]] = getelementptr inbounds nuw i8, ptr [[START]], i32 4 // CHECK: store ptr [[NEXT]], ptr %mylist // CHECK: [[RES:%.*]] = load i32, ptr [[START]] @@ -28,9 +28,9 @@ typedef struct { long long test_longlong(OneLongLong input, va_list *mylist) { // CHECK-LABEL: define{{.*}} i64 @test_longlong(i64 %input // CHECK: [[STARTPTR:%.*]] = load ptr, ptr %mylist - // CHECK: [[ALIGN_TMP:%.+]] = getelementptr inbounds i8, ptr [[STARTPTR]], i32 7 + // CHECK: [[ALIGN_TMP:%.+]] = getelementptr inbounds nuw i8, ptr [[STARTPTR]], i32 7 // CHECK: [[ALIGNED_ADDR:%.+]] = tail call align 8 ptr @llvm.ptrmask.p0.i32(ptr nonnull [[ALIGN_TMP]], i32 -8) - // CHECK: [[NEXT:%.*]] = getelementptr inbounds i8, ptr [[ALIGNED_ADDR]], i32 8 + // CHECK: [[NEXT:%.*]] = getelementptr inbounds nuw i8, ptr [[ALIGNED_ADDR]], i32 8 // CHECK: store ptr [[NEXT]], ptr %mylist // CHECK: [[RES:%.*]] = load i64, ptr [[ALIGNED_ADDR]] @@ -49,7 +49,7 @@ float test_hfa(va_list *mylist) { // CHECK-LABEL: define{{.*}} float @test_hfa // CHECK: [[START:%.*]] = load ptr, ptr %mylist -// CHECK: [[NEXT:%.*]] = getelementptr inbounds i8, ptr [[START]], i32 16 +// CHECK: [[NEXT:%.*]] = getelementptr inbounds nuw i8, ptr [[START]], i32 16 // CHECK: store ptr [[NEXT]], ptr %mylist // CHECK: [[RES:%.*]] = load float, ptr [[START]] @@ -76,7 +76,7 @@ typedef struct { long long test_bigstruct(BigStruct input, va_list *mylist) { // CHECK-LABEL: define{{.*}} i64 @test_bigstruct(ptr // CHECK: [[START:%.*]] = load ptr, ptr %mylist -// CHECK: [[NEXT:%.*]] = getelementptr inbounds i8, ptr [[START]], i32 4 +// CHECK: [[NEXT:%.*]] = getelementptr inbounds nuw i8, ptr [[START]], i32 4 // CHECK: store ptr [[NEXT]], ptr %mylist // CHECK: [[ADDR:%.*]] = load ptr, ptr [[START]] @@ -97,7 +97,7 @@ short test_threeshorts(ThreeShorts input, va_list *mylist) { // CHECK-LABEL: define{{.*}} signext i16 @test_threeshorts([2 x i32] %input // CHECK: [[START:%.*]] = load ptr, ptr %mylist -// CHECK: [[NEXT:%.*]] = getelementptr inbounds i8, ptr [[START]], i32 8 +// CHECK: [[NEXT:%.*]] = getelementptr inbounds nuw i8, ptr [[START]], i32 8 // CHECK: store ptr [[NEXT]], ptr %mylist // CHECK: [[RES:%.*]] = load i16, ptr [[START]] diff --git a/clang/test/CodeGen/attr-arm-sve-vector-bits-bitcast.c b/clang/test/CodeGen/attr-arm-sve-vector-bits-bitcast.c index a7c87e32a58eb..c5a410193bfb7 100644 --- a/clang/test/CodeGen/attr-arm-sve-vector-bits-bitcast.c +++ b/clang/test/CodeGen/attr-arm-sve-vector-bits-bitcast.c @@ -32,21 +32,21 @@ DEFINE_STRUCT(bool) // CHECK-128-NEXT: entry: // CHECK-128-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 16 // CHECK-128-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr [[Y]], align 16, !tbaa [[TBAA2:![0-9]+]] -// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i64.v2i64( undef, <2 x i64> [[TMP0]], i64 0) +// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i64.v2i64( poison, <2 x i64> [[TMP0]], i64 0) // CHECK-128-NEXT: ret [[CAST_SCALABLE]] // // CHECK-256-LABEL: @read_int64( // CHECK-256-NEXT: entry: // CHECK-256-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 32 // CHECK-256-NEXT: [[TMP0:%.*]] = load <4 x i64>, ptr [[Y]], align 16, !tbaa [[TBAA2:![0-9]+]] -// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i64.v4i64( undef, <4 x i64> [[TMP0]], i64 0) +// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i64.v4i64( poison, <4 x i64> [[TMP0]], i64 0) // CHECK-256-NEXT: ret [[CAST_SCALABLE]] // // CHECK-512-LABEL: @read_int64( // CHECK-512-NEXT: entry: // CHECK-512-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 64 // CHECK-512-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr [[Y]], align 16, !tbaa [[TBAA2:![0-9]+]] -// CHECK-512-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i64.v8i64( undef, <8 x i64> [[TMP0]], i64 0) +// CHECK-512-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i64.v8i64( poison, <8 x i64> [[TMP0]], i64 0) // CHECK-512-NEXT: ret [[CAST_SCALABLE]] // svint64_t read_int64(struct struct_int64 *s) { @@ -86,21 +86,21 @@ void write_int64(struct struct_int64 *s, svint64_t x) { // CHECK-128-NEXT: entry: // CHECK-128-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 16 // CHECK-128-NEXT: [[TMP0:%.*]] = load <2 x double>, ptr [[Y]], align 16, !tbaa [[TBAA2]] -// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2f64.v2f64( undef, <2 x double> [[TMP0]], i64 0) +// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2f64.v2f64( poison, <2 x double> [[TMP0]], i64 0) // CHECK-128-NEXT: ret [[CAST_SCALABLE]] // // CHECK-256-LABEL: @read_float64( // CHECK-256-NEXT: entry: // CHECK-256-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 32 // CHECK-256-NEXT: [[TMP0:%.*]] = load <4 x double>, ptr [[Y]], align 16, !tbaa [[TBAA2]] -// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2f64.v4f64( undef, <4 x double> [[TMP0]], i64 0) +// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2f64.v4f64( poison, <4 x double> [[TMP0]], i64 0) // CHECK-256-NEXT: ret [[CAST_SCALABLE]] // // CHECK-512-LABEL: @read_float64( // CHECK-512-NEXT: entry: // CHECK-512-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 64 // CHECK-512-NEXT: [[TMP0:%.*]] = load <8 x double>, ptr [[Y]], align 16, !tbaa [[TBAA2]] -// CHECK-512-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2f64.v8f64( undef, <8 x double> [[TMP0]], i64 0) +// CHECK-512-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2f64.v8f64( poison, <8 x double> [[TMP0]], i64 0) // CHECK-512-NEXT: ret [[CAST_SCALABLE]] // svfloat64_t read_float64(struct struct_float64 *s) { @@ -140,21 +140,21 @@ void write_float64(struct struct_float64 *s, svfloat64_t x) { // CHECK-128-NEXT: entry: // CHECK-128-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 16 // CHECK-128-NEXT: [[TMP0:%.*]] = load <8 x bfloat>, ptr [[Y]], align 16, !tbaa [[TBAA2]] -// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8bf16.v8bf16( undef, <8 x bfloat> [[TMP0]], i64 0) +// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8bf16.v8bf16( poison, <8 x bfloat> [[TMP0]], i64 0) // CHECK-128-NEXT: ret [[CAST_SCALABLE]] // // CHECK-256-LABEL: @read_bfloat16( // CHECK-256-NEXT: entry: // CHECK-256-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 32 // CHECK-256-NEXT: [[TMP0:%.*]] = load <16 x bfloat>, ptr [[Y]], align 16, !tbaa [[TBAA2]] -// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8bf16.v16bf16( undef, <16 x bfloat> [[TMP0]], i64 0) +// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8bf16.v16bf16( poison, <16 x bfloat> [[TMP0]], i64 0) // CHECK-256-NEXT: ret [[CAST_SCALABLE]] // // CHECK-512-LABEL: @read_bfloat16( // CHECK-512-NEXT: entry: // CHECK-512-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 64 // CHECK-512-NEXT: [[TMP0:%.*]] = load <32 x bfloat>, ptr [[Y]], align 16, !tbaa [[TBAA2]] -// CHECK-512-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8bf16.v32bf16( undef, <32 x bfloat> [[TMP0]], i64 0) +// CHECK-512-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv8bf16.v32bf16( poison, <32 x bfloat> [[TMP0]], i64 0) // CHECK-512-NEXT: ret [[CAST_SCALABLE]] // svbfloat16_t read_bfloat16(struct struct_bfloat16 *s) { @@ -194,7 +194,7 @@ void write_bfloat16(struct struct_bfloat16 *s, svbfloat16_t x) { // CHECK-128-NEXT: entry: // CHECK-128-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 2 // CHECK-128-NEXT: [[TMP0:%.*]] = load <2 x i8>, ptr [[Y]], align 2, !tbaa [[TBAA2]] -// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v2i8( undef, <2 x i8> [[TMP0]], i64 0) +// CHECK-128-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v2i8( poison, <2 x i8> [[TMP0]], i64 0) // CHECK-128-NEXT: [[TMP1:%.*]] = bitcast [[CAST_SCALABLE]] to // CHECK-128-NEXT: ret [[TMP1]] // @@ -202,7 +202,7 @@ void write_bfloat16(struct struct_bfloat16 *s, svbfloat16_t x) { // CHECK-256-NEXT: entry: // CHECK-256-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 4 // CHECK-256-NEXT: [[TMP0:%.*]] = load <4 x i8>, ptr [[Y]], align 2, !tbaa [[TBAA2]] -// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v4i8( undef, <4 x i8> [[TMP0]], i64 0) +// CHECK-256-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v4i8( poison, <4 x i8> [[TMP0]], i64 0) // CHECK-256-NEXT: [[TMP1:%.*]] = bitcast [[CAST_SCALABLE]] to // CHECK-256-NEXT: ret [[TMP1]] // @@ -210,7 +210,7 @@ void write_bfloat16(struct struct_bfloat16 *s, svbfloat16_t x) { // CHECK-512-NEXT: entry: // CHECK-512-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr [[S:%.*]], i64 8 // CHECK-512-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr [[Y]], align 2, !tbaa [[TBAA2]] -// CHECK-512-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v8i8( undef, <8 x i8> [[TMP0]], i64 0) +// CHECK-512-NEXT: [[CAST_SCALABLE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v8i8( poison, <8 x i8> [[TMP0]], i64 0) // CHECK-512-NEXT: [[TMP1:%.*]] = bitcast [[CAST_SCALABLE]] to // CHECK-512-NEXT: ret [[TMP1]] // diff --git a/clang/test/CodeGen/attr-arm-sve-vector-bits-cast.c b/clang/test/CodeGen/attr-arm-sve-vector-bits-cast.c index cdfe6d5df848b..e1e2220f94d6d 100644 --- a/clang/test/CodeGen/attr-arm-sve-vector-bits-cast.c +++ b/clang/test/CodeGen/attr-arm-sve-vector-bits-cast.c @@ -75,7 +75,7 @@ svint64_t lax_cast(fixed_int32_t type) { // CHECK-LABEL: @to_svint32_t__from_gnu_int32_t( // CHECK-NEXT: entry: // CHECK-NEXT: [[TYPE:%.*]] = load <16 x i32>, ptr [[TMP0:%.*]], align 16, !tbaa [[TBAA6]] -// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv4i32.v16i32( undef, <16 x i32> [[TYPE]], i64 0) +// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv4i32.v16i32( poison, <16 x i32> [[TYPE]], i64 0) // CHECK-NEXT: ret [[CASTSCALABLESVE]] // svint32_t to_svint32_t__from_gnu_int32_t(gnu_int32_t type) { diff --git a/clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c b/clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c index c643bcf61455b..06fbb0027d7c1 100644 --- a/clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c +++ b/clang/test/CodeGen/attr-arm-sve-vector-bits-codegen.c @@ -24,16 +24,16 @@ fixed_int32_t global_vec; // CHECK-NEXT: store [[VEC:%.*]], ptr [[VEC_ADDR]], align 16 // CHECK-NEXT: [[TMP0:%.*]] = load , ptr [[PRED_ADDR]], align 2 // CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr @global_pred, align 2 -// CHECK-NEXT: [[CASTFIXEDSVE:%.*]] = call @llvm.vector.insert.nxv2i8.v8i8( undef, <8 x i8> [[TMP1]], i64 0) +// CHECK-NEXT: [[CASTFIXEDSVE:%.*]] = call @llvm.vector.insert.nxv2i8.v8i8( poison, <8 x i8> [[TMP1]], i64 0) // CHECK-NEXT: [[TMP2:%.*]] = bitcast [[CASTFIXEDSVE]] to // CHECK-NEXT: [[TMP3:%.*]] = load <8 x i8>, ptr @global_pred, align 2 -// CHECK-NEXT: [[CASTFIXEDSVE2:%.*]] = call @llvm.vector.insert.nxv2i8.v8i8( undef, <8 x i8> [[TMP3]], i64 0) +// CHECK-NEXT: [[CASTFIXEDSVE2:%.*]] = call @llvm.vector.insert.nxv2i8.v8i8( poison, <8 x i8> [[TMP3]], i64 0) // CHECK-NEXT: [[TMP4:%.*]] = bitcast [[CASTFIXEDSVE2]] to // CHECK-NEXT: [[TMP5:%.*]] = call @llvm.aarch64.sve.and.z.nxv16i1( [[TMP0]], [[TMP2]], [[TMP4]]) // CHECK-NEXT: store [[TMP5]], ptr [[PG]], align 2 // CHECK-NEXT: [[TMP6:%.*]] = load , ptr [[PG]], align 2 // CHECK-NEXT: [[TMP7:%.*]] = load <16 x i32>, ptr @global_vec, align 16 -// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call @llvm.vector.insert.nxv4i32.v16i32( undef, <16 x i32> [[TMP7]], i64 0) +// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call @llvm.vector.insert.nxv4i32.v16i32( poison, <16 x i32> [[TMP7]], i64 0) // CHECK-NEXT: [[TMP8:%.*]] = load , ptr [[VEC_ADDR]], align 16 // CHECK-NEXT: [[TMP9:%.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[TMP6]]) // CHECK-NEXT: [[TMP10:%.*]] = call @llvm.aarch64.sve.add.nxv4i32( [[TMP9]], [[CASTSCALABLESVE]], [[TMP8]]) @@ -121,18 +121,18 @@ fixed_bool_t address_of_array_idx() { // CHECK-NEXT: store <8 x i8> , ptr [[YY]], align 8 // CHECK-NEXT: [[TMP0:%.*]] = load , ptr [[PRED_ADDR]], align 2 // CHECK-NEXT: [[TMP1:%.*]] = load <8 x i8>, ptr @global_pred, align 2 -// CHECK-NEXT: [[CASTFIXEDSVE:%.*]] = call @llvm.vector.insert.nxv2i8.v8i8( undef, <8 x i8> [[TMP1]], i64 0) +// CHECK-NEXT: [[CASTFIXEDSVE:%.*]] = call @llvm.vector.insert.nxv2i8.v8i8( poison, <8 x i8> [[TMP1]], i64 0) // CHECK-NEXT: [[TMP2:%.*]] = bitcast [[CASTFIXEDSVE]] to // CHECK-NEXT: [[TMP3:%.*]] = load <8 x i8>, ptr [[XX]], align 8 // CHECK-NEXT: [[TMP4:%.*]] = load <8 x i8>, ptr [[YY]], align 8 // CHECK-NEXT: [[ADD:%.*]] = add <8 x i8> [[TMP3]], [[TMP4]] -// CHECK-NEXT: [[CASTFIXEDSVE2:%.*]] = call @llvm.vector.insert.nxv2i8.v8i8( undef, <8 x i8> [[ADD]], i64 0) +// CHECK-NEXT: [[CASTFIXEDSVE2:%.*]] = call @llvm.vector.insert.nxv2i8.v8i8( poison, <8 x i8> [[ADD]], i64 0) // CHECK-NEXT: [[TMP5:%.*]] = bitcast [[CASTFIXEDSVE2]] to // CHECK-NEXT: [[TMP6:%.*]] = call @llvm.aarch64.sve.and.z.nxv16i1( [[TMP0]], [[TMP2]], [[TMP5]]) // CHECK-NEXT: store [[TMP6]], ptr [[PG]], align 2 // CHECK-NEXT: [[TMP7:%.*]] = load , ptr [[PG]], align 2 // CHECK-NEXT: [[TMP8:%.*]] = load <16 x i32>, ptr @global_vec, align 16 -// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call @llvm.vector.insert.nxv4i32.v16i32( undef, <16 x i32> [[TMP8]], i64 0) +// CHECK-NEXT: [[CASTSCALABLESVE:%.*]] = call @llvm.vector.insert.nxv4i32.v16i32( poison, <16 x i32> [[TMP8]], i64 0) // CHECK-NEXT: [[TMP9:%.*]] = load , ptr [[VEC_ADDR]], align 16 // CHECK-NEXT: [[TMP10:%.*]] = call @llvm.aarch64.sve.convert.from.svbool.nxv4i1( [[TMP7]]) // CHECK-NEXT: [[TMP11:%.*]] = call @llvm.aarch64.sve.add.nxv4i32( [[TMP10]], [[CASTSCALABLESVE]], [[TMP9]]) diff --git a/clang/test/CodeGen/attr-arm-sve-vector-bits-globals.c b/clang/test/CodeGen/attr-arm-sve-vector-bits-globals.c index 7858a7bf0026e..011518c60f52f 100644 --- a/clang/test/CodeGen/attr-arm-sve-vector-bits-globals.c +++ b/clang/test/CodeGen/attr-arm-sve-vector-bits-globals.c @@ -71,13 +71,13 @@ void write_global_bool(svbool_t v) { global_bool = v; } // CHECK-128-LABEL: @read_global_i64( // CHECK-128-NEXT: entry: // CHECK-128-NEXT: [[TMP0:%.*]] = load <2 x i64>, ptr @global_i64, align 16, !tbaa [[TBAA6]] -// CHECK-128-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv2i64.v2i64( undef, <2 x i64> [[TMP0]], i64 0) +// CHECK-128-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv2i64.v2i64( poison, <2 x i64> [[TMP0]], i64 0) // CHECK-128-NEXT: ret [[CASTSCALABLESVE]] // // CHECK-512-LABEL: @read_global_i64( // CHECK-512-NEXT: entry: // CHECK-512-NEXT: [[TMP0:%.*]] = load <8 x i64>, ptr @global_i64, align 16, !tbaa [[TBAA6]] -// CHECK-512-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv2i64.v8i64( undef, <8 x i64> [[TMP0]], i64 0) +// CHECK-512-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv2i64.v8i64( poison, <8 x i64> [[TMP0]], i64 0) // CHECK-512-NEXT: ret [[CASTSCALABLESVE]] // svint64_t read_global_i64() { return global_i64; } @@ -85,13 +85,13 @@ svint64_t read_global_i64() { return global_i64; } // CHECK-128-LABEL: @read_global_bf16( // CHECK-128-NEXT: entry: // CHECK-128-NEXT: [[TMP0:%.*]] = load <8 x bfloat>, ptr @global_bf16, align 16, !tbaa [[TBAA6]] -// CHECK-128-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv8bf16.v8bf16( undef, <8 x bfloat> [[TMP0]], i64 0) +// CHECK-128-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv8bf16.v8bf16( poison, <8 x bfloat> [[TMP0]], i64 0) // CHECK-128-NEXT: ret [[CASTSCALABLESVE]] // // CHECK-512-LABEL: @read_global_bf16( // CHECK-512-NEXT: entry: // CHECK-512-NEXT: [[TMP0:%.*]] = load <32 x bfloat>, ptr @global_bf16, align 16, !tbaa [[TBAA6]] -// CHECK-512-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv8bf16.v32bf16( undef, <32 x bfloat> [[TMP0]], i64 0) +// CHECK-512-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv8bf16.v32bf16( poison, <32 x bfloat> [[TMP0]], i64 0) // CHECK-512-NEXT: ret [[CASTSCALABLESVE]] // svbfloat16_t read_global_bf16() { return global_bf16; } @@ -99,14 +99,14 @@ svbfloat16_t read_global_bf16() { return global_bf16; } // CHECK-128-LABEL: @read_global_bool( // CHECK-128-NEXT: entry: // CHECK-128-NEXT: [[TMP0:%.*]] = load <2 x i8>, ptr @global_bool, align 2, !tbaa [[TBAA6]] -// CHECK-128-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v2i8( undef, <2 x i8> [[TMP0]], i64 0) +// CHECK-128-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v2i8( poison, <2 x i8> [[TMP0]], i64 0) // CHECK-128-NEXT: [[TMP1:%.*]] = bitcast [[CASTSCALABLESVE]] to // CHECK-128-NEXT: ret [[TMP1]] // // CHECK-512-LABEL: @read_global_bool( // CHECK-512-NEXT: entry: // CHECK-512-NEXT: [[TMP0:%.*]] = load <8 x i8>, ptr @global_bool, align 2, !tbaa [[TBAA6]] -// CHECK-512-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v8i8( undef, <8 x i8> [[TMP0]], i64 0) +// CHECK-512-NEXT: [[CASTSCALABLESVE:%.*]] = tail call @llvm.vector.insert.nxv2i8.v8i8( poison, <8 x i8> [[TMP0]], i64 0) // CHECK-512-NEXT: [[TMP1:%.*]] = bitcast [[CASTSCALABLESVE]] to // CHECK-512-NEXT: ret [[TMP1]] // diff --git a/clang/test/CodeGen/attr-counted-by-pr110385.c b/clang/test/CodeGen/attr-counted-by-pr110385.c index e120dcc583578..c2ff032334fe2 100644 --- a/clang/test/CodeGen/attr-counted-by-pr110385.c +++ b/clang/test/CodeGen/attr-counted-by-pr110385.c @@ -31,7 +31,7 @@ void init(void * __attribute__((pass_dynamic_object_size(0)))); // CHECK-NEXT: [[GROWABLE:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 // CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[GROWABLE]], align 8, !tbaa [[TBAA2:![0-9]+]] // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 12 -// CHECK-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8 +// CHECK-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 8 // CHECK-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // CHECK-NEXT: [[TMP1:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 // CHECK-NEXT: [[TMP2:%.*]] = shl nsw i64 [[TMP1]], 1 @@ -48,7 +48,7 @@ void test1(struct bucket *foo) { // CHECK-SAME: ptr noundef [[FOO:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: entry: // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 16 -// CHECK-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 12 +// CHECK-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 12 // CHECK-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // CHECK-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 // CHECK-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 1 diff --git a/clang/test/CodeGen/attr-counted-by.c b/clang/test/CodeGen/attr-counted-by.c index a5efe35181b5e..be4c7f07e9215 100644 --- a/clang/test/CodeGen/attr-counted-by.c +++ b/clang/test/CodeGen/attr-counted-by.c @@ -60,17 +60,17 @@ struct anon_struct { // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[VAL:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2:![0-9]+]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9:[0-9]+]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8:[0-9]+]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] // SANITIZE-WITH-ATTR-NEXT: store i32 [[VAL]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4:![0-9]+]] // SANITIZE-WITH-ATTR-NEXT: ret void // @@ -108,13 +108,13 @@ void test1(struct annotated *p, int index, int val) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test2( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[INDEX]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB3:[0-9]+]], i64 [[INDEX]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB3:[0-9]+]], i64 [[INDEX]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 @@ -127,7 +127,7 @@ void test1(struct annotated *p, int index, int val) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test2( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1:[0-9]+]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[TMP0]], 2 @@ -159,7 +159,7 @@ void test2(struct annotated *p, size_t index) { // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test2_bdos( // SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 2 @@ -170,7 +170,7 @@ void test2(struct annotated *p, size_t index) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -8589934592, 8589934589) i64 @test2_bdos( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2:[0-9]+]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl nsw i64 [[TMP0]], 2 @@ -195,13 +195,13 @@ size_t test2_bdos(struct annotated *p) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test3( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[INDEX]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[INDEX]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[INDEX]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 @@ -266,7 +266,7 @@ size_t test3_bdos(struct annotated *p) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test4( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 @@ -274,7 +274,7 @@ size_t test3_bdos(struct annotated *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT4:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont4: // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], 2 @@ -282,53 +282,50 @@ size_t test3_bdos(struct annotated *p) { // SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = add i32 [[TMP3]], 244 // SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = and i32 [[TMP4]], 252 // SANITIZE-WITH-ATTR-NEXT: [[CONV1:%.*]] = select i1 [[TMP2]], i32 [[TMP5]], i32 0 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] // SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV1]], ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD6:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[ADD:%.*]] = add nsw i32 [[INDEX]], 1 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM12:%.*]] = sext i32 [[ADD]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD6]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp ult i64 [[IDXPROM12]], [[TMP6]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP7]], label [[CONT19:%.*]], label [[HANDLER_OUT_OF_BOUNDS15:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP6:%.*]] = icmp ult i64 [[IDXPROM12]], [[TMP0]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP6]], label [[CONT19:%.*]], label [[HANDLER_OUT_OF_BOUNDS15:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds15: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM12]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB6:[0-9]+]], i64 [[IDXPROM12]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont19: -// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD6]], 3 -// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD6]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = add i32 [[TMP9]], 240 -// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = and i32 [[TMP10]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[CONV8:%.*]] = select i1 [[TMP8]], i32 [[TMP11]], i32 0 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM12]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP7:%.*]] = icmp sgt i32 [[DOT_COUNTED_BY_LOAD]], 3 +// SANITIZE-WITH-ATTR-NEXT: [[TMP8:%.*]] = add i32 [[TMP3]], 240 +// SANITIZE-WITH-ATTR-NEXT: [[TMP9:%.*]] = and i32 [[TMP8]], 252 +// SANITIZE-WITH-ATTR-NEXT: [[CONV8:%.*]] = select i1 [[TMP7]], i32 [[TMP9]], i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM12]] // SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV8]], ptr [[ARRAYIDX17]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD21:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[ADD27:%.*]] = add nsw i32 [[INDEX]], 2 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM28:%.*]] = sext i32 [[ADD27]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD21]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = icmp ult i64 [[IDXPROM28]], [[TMP12]], !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP13]], label [[CONT35:%.*]], label [[HANDLER_OUT_OF_BOUNDS31:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP10:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD21]] to i64, !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP11:%.*]] = icmp ult i64 [[IDXPROM28]], [[TMP10]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP11]], label [[CONT35:%.*]], label [[HANDLER_OUT_OF_BOUNDS31:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds31: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[IDXPROM28]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB7:[0-9]+]], i64 [[IDXPROM28]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont35: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM28]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = icmp sgt i32 [[FAM_IDX]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD21]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = sext i32 [[FAM_IDX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = sub nsw i64 [[TMP15]], [[TMP16]] -// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = icmp sgt i64 [[TMP17]], -1 -// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = and i1 [[TMP14]], [[TMP18]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP17]] to i32 -// SANITIZE-WITH-ATTR-NEXT: [[TMP20:%.*]] = shl i32 [[DOTTR]], 2 -// SANITIZE-WITH-ATTR-NEXT: [[TMP21:%.*]] = and i32 [[TMP20]], 252 -// SANITIZE-WITH-ATTR-NEXT: [[CONV23:%.*]] = select i1 [[TMP19]], i32 [[TMP21]], i32 0 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX33:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM28]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP12:%.*]] = icmp sgt i32 [[FAM_IDX]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP13:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD21]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP14:%.*]] = sext i32 [[FAM_IDX]] to i64 +// SANITIZE-WITH-ATTR-NEXT: [[TMP15:%.*]] = sub nsw i64 [[TMP13]], [[TMP14]] +// SANITIZE-WITH-ATTR-NEXT: [[TMP16:%.*]] = icmp sgt i64 [[TMP15]], -1 +// SANITIZE-WITH-ATTR-NEXT: [[TMP17:%.*]] = and i1 [[TMP12]], [[TMP16]] +// SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP15]] to i32 +// SANITIZE-WITH-ATTR-NEXT: [[TMP18:%.*]] = shl i32 [[DOTTR]], 2 +// SANITIZE-WITH-ATTR-NEXT: [[TMP19:%.*]] = and i32 [[TMP18]], 252 +// SANITIZE-WITH-ATTR-NEXT: [[CONV23:%.*]] = select i1 [[TMP17]], i32 [[TMP19]], i32 0 // SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV23]], ptr [[ARRAYIDX33]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test4( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]], i32 noundef [[FAM_IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = shl i32 [[DOT_COUNTED_BY_LOAD]], 2 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], 244 @@ -410,7 +407,7 @@ void test4(struct annotated *p, int index, int fam_idx) { // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869180, 17179869181) i64 @test4_bdos( // SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64 @@ -425,7 +422,7 @@ void test4(struct annotated *p, int index, int fam_idx) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 -17179869180, 17179869181) i64 @test4_bdos( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = sext i32 [[DOT_COUNTED_BY_LOAD]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = sext i32 [[INDEX]] to i64 @@ -455,12 +452,12 @@ size_t test4_bdos(struct annotated *p, int index) { // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOTCOUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[DOTCOUNTED_BY_LOAD]], [[IDXPROM]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 @@ -526,13 +523,13 @@ size_t test5_bdos(struct anon_struct *p) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test6( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i64 [[DOT_COUNTED_BY_LOAD]], [[IDXPROM]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 16 @@ -546,7 +543,7 @@ size_t test5_bdos(struct anon_struct *p) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test6( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOT_COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[DOT_COUNTED_BY_LOAD]], i64 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[DOTTR:%.*]] = trunc i64 [[TMP0]] to i32 @@ -582,7 +579,7 @@ void test6(struct anon_struct *p, int index) { // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, -3) i64 @test6_bdos( // SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[DOT_COUNTED_BY_LOAD]], i64 0) // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 2 @@ -591,7 +588,7 @@ void test6(struct anon_struct *p, int index) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, -3) i64 @test6_bdos( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i64, ptr [[DOT_COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = tail call i64 @llvm.smax.i64(i64 [[DOT_COUNTED_BY_LOAD]], i64 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = shl i64 [[TMP0]], 2 @@ -614,18 +611,18 @@ size_t test6_bdos(struct anon_struct *p) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test7( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i8, ptr [[TMP0]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i8 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP1]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont7: // SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] // SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8:![0-9]+]] // SANITIZE-WITH-ATTR-NEXT: ret void // @@ -687,27 +684,27 @@ size_t test7_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test8( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB12:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont7: -// SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] // SANITIZE-WITH-ATTR-NEXT: store i8 [[DOT_COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] // SANITIZE-WITH-ATTR-NEXT: ret void // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test8( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOT_COUNTED_BY_GEP]], align 4 -// NO-SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 9 +// NO-SANITIZE-WITH-ATTR-NEXT: [[INTS:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 9 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[INTS]], i64 0, i64 [[IDXPROM]] // NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[DOT_COUNTED_BY_LOAD]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] @@ -738,7 +735,7 @@ void test8(struct union_of_fams *p, int index) { // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 256) i64 @test8_bdos( // SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64 // SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] @@ -746,7 +743,7 @@ void test8(struct union_of_fams *p, int index) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 256) i64 @test8_bdos( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i8, ptr [[DOT_COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i8 [[DOT_COUNTED_BY_LOAD]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: ret i64 [[TMP0]] @@ -768,18 +765,18 @@ size_t test8_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test9( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[TMP0]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP1]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB14:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB14:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont7: // SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] // SANITIZE-WITH-ATTR-NEXT: store i8 -1, ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] // SANITIZE-WITH-ATTR-NEXT: ret void // @@ -841,18 +838,18 @@ size_t test9_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR-LABEL: define dso_local void @test10( // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT7:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont7: -// SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] // SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) // SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i32 [[NARROW]] to i8 // SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA8]] @@ -861,11 +858,11 @@ size_t test9_bdos(struct union_of_fams *p) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test10( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR1]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = trunc i32 [[NARROW]] to i8 -// NO-SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 +// NO-SANITIZE-WITH-ATTR-NEXT: [[BYTES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i8], ptr [[BYTES]], i64 0, i64 [[IDXPROM]] // NO-SANITIZE-WITH-ATTR-NEXT: store i8 [[CONV]], ptr [[ARRAYIDX]], align 1, !tbaa [[TBAA6]] @@ -896,7 +893,7 @@ void test10(struct union_of_fams *p, int index) { // SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test10_bdos( // SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext nneg i32 [[NARROW]] to i64 @@ -905,7 +902,7 @@ void test10(struct union_of_fams *p, int index) { // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local range(i64 0, 2147483648) i64 @test10_bdos( // NO-SANITIZE-WITH-ATTR-SAME: ptr nocapture noundef readonly [[P:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[NARROW:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext nneg i32 [[NARROW]] to i64 @@ -929,17 +926,17 @@ size_t test10_bdos(struct union_of_fams *p) { // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB16:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB16:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM]] // SANITIZE-WITH-ATTR-NEXT: store i32 4, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: ret void // @@ -1017,26 +1014,26 @@ int test12_a, test12_b; // SANITIZE-WITH-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR4:[0-9]+]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[BAZ:%.*]] = alloca [[STRUCT_HANG:%.*]], align 4 -// SANITIZE-WITH-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR10:[0-9]+]] +// SANITIZE-WITH-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR9:[0-9]+]] // SANITIZE-WITH-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) [[BAZ]], ptr noundef nonnull align 4 dereferenceable(24) @test12_bar, i64 24, i1 false), !tbaa.struct [[TBAA_STRUCT9:![0-9]+]] // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[INDEX]], 6 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[INDEX]] to i64 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB18:[0-9]+]], i64 [[TMP1]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB18:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[TMP1]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [6 x i32], ptr [[BAZ]], i64 0, i64 [[TMP1]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP2]], ptr @test12_b, align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr @test12_foo, align 4 // SANITIZE-WITH-ATTR-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[DOTCOUNTED_BY_LOAD]], 0 // SANITIZE-WITH-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF10:![0-9]+]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds4: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB20:[0-9]+]], i64 0) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB20:[0-9]+]], i64 0) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.type_mismatch6: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB21:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB21:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local noundef i32 @test12( @@ -1046,7 +1043,7 @@ int test12_a, test12_b; // NO-SANITIZE-WITH-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR11:[0-9]+]] // NO-SANITIZE-WITH-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) [[BAZ]], ptr noundef nonnull align 4 dereferenceable(24) @test12_bar, i64 24, i1 false), !tbaa.struct [[TBAA_STRUCT7:![0-9]+]] // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [6 x i32], ptr [[BAZ]], i64 0, i64 [[IDXPROM]] // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITH-ATTR-NEXT: store i32 [[TMP0]], ptr @test12_b, align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4), align 4, !tbaa [[TBAA2]] @@ -1059,26 +1056,26 @@ int test12_a, test12_b; // SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: [[BAZ:%.*]] = alloca [[STRUCT_HANG:%.*]], align 4 -// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR7:[0-9]+]] +// SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR6:[0-9]+]] // SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) [[BAZ]], ptr noundef nonnull align 4 dereferenceable(24) @test12_bar, i64 24, i1 false), !tbaa.struct [[TBAA_STRUCT7:![0-9]+]] // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = icmp ult i32 [[INDEX]], 6 // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[INDEX]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8:![0-9]+]], !nosanitize [[META9:![0-9]+]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP1]]) #[[ATTR8:[0-9]+]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP1]]) #[[ATTR7:[0-9]+]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: cont: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[TMP1]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [6 x i32], ptr [[BAZ]], i64 0, i64 [[TMP1]] // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP2]], ptr @test12_b, align 4, !tbaa [[TBAA2]] // SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr @test12_foo, align 4 // SANITIZE-WITHOUT-ATTR-NEXT: [[DOTNOT:%.*]] = icmp eq i32 [[DOTCOUNTED_BY_LOAD]], 0 // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[DOTNOT]], label [[HANDLER_OUT_OF_BOUNDS4:%.*]], label [[HANDLER_TYPE_MISMATCH6:%.*]], !prof [[PROF10:![0-9]+]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds4: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 0) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 0) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.type_mismatch6: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_type_mismatch_v1_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 ptrtoint (ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4) to i64)) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local noundef i32 @test12( @@ -1088,7 +1085,7 @@ int test12_a, test12_b; // NO-SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.lifetime.start.p0(i64 24, ptr nonnull [[BAZ]]) #[[ATTR9:[0-9]+]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: call void @llvm.memcpy.p0.p0.i64(ptr noundef nonnull align 4 dereferenceable(24) [[BAZ]], ptr noundef nonnull align 4 dereferenceable(24) @test12_bar, i64 24, i1 false), !tbaa.struct [[TBAA_STRUCT7:![0-9]+]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[INDEX]] to i64 -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [6 x i32], ptr [[BAZ]], i64 0, i64 [[IDXPROM]] +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [6 x i32], ptr [[BAZ]], i64 0, i64 [[IDXPROM]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: store i32 [[TMP0]], ptr @test12_b, align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr getelementptr inbounds nuw (i8, ptr @test12_foo, i64 4), align 4, !tbaa [[TBAA2]] @@ -1120,17 +1117,17 @@ struct test13_bar { // SANITIZE-WITH-ATTR-SAME: i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr @test13_f, align 8, !tbaa [[TBAA11:![0-9]+]] -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[INDEX]], [[TMP1]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP2]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB24:[0-9]+]], i64 [[INDEX]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB24:[0-9]+]], i64 [[INDEX]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont5: // SANITIZE-WITH-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 16 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[INDEX]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[INDEX]] // SANITIZE-WITH-ATTR-NEXT: store ptr null, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA15:![0-9]+]] // SANITIZE-WITH-ATTR-NEXT: ret i32 0 // @@ -1147,17 +1144,17 @@ struct test13_bar { // SANITIZE-WITHOUT-ATTR-SAME: i64 noundef [[INDEX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr @test13_f, align 8, !tbaa [[TBAA11:![0-9]+]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8 +// SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 8 // SANITIZE-WITHOUT-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = icmp ult i64 [[INDEX]], [[TMP1]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP2]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[INDEX]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB8:[0-9]+]], i64 [[INDEX]]) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: cont5: // SANITIZE-WITHOUT-ATTR-NEXT: [[REVMAP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 16 -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[INDEX]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x ptr], ptr [[REVMAP]], i64 0, i64 [[INDEX]] // SANITIZE-WITHOUT-ATTR-NEXT: store ptr null, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA15:![0-9]+]] // SANITIZE-WITHOUT-ATTR-NEXT: ret i32 0 // @@ -1184,14 +1181,13 @@ struct test14_foo { // SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp eq i32 [[IDX]], 0 -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[TRAP:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB25:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB25:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: trap: -// SANITIZE-WITH-ATTR-NEXT: tail call void @llvm.trap() #[[ATTR9]] -// SANITIZE-WITH-ATTR-NEXT: unreachable +// SANITIZE-WITH-ATTR: cont3: +// SANITIZE-WITH-ATTR-NEXT: ret i32 undef // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test14( // NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] { @@ -1210,14 +1206,13 @@ struct test14_foo { // SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = icmp eq i32 [[IDX]], 0 -// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[TRAP:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: // SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB9:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR: trap: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @llvm.trap() #[[ATTR8]] -// SANITIZE-WITHOUT-ATTR-NEXT: unreachable +// SANITIZE-WITHOUT-ATTR: cont3: +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 undef // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test14( // NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { @@ -1240,14 +1235,13 @@ int test14(int idx) { // SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp eq i32 [[IDX]], 0 -// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[TRAP:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB27:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB27:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR: trap: -// SANITIZE-WITH-ATTR-NEXT: tail call void @llvm.trap() #[[ATTR9]] -// SANITIZE-WITH-ATTR-NEXT: unreachable +// SANITIZE-WITH-ATTR: cont1: +// SANITIZE-WITH-ATTR-NEXT: ret i32 undef // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test15( // NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] { @@ -1261,14 +1255,13 @@ int test14(int idx) { // SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = icmp eq i32 [[IDX]], 0 -// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[TRAP:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT1:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: // SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX]] to i64 -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB11:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR: trap: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @llvm.trap() #[[ATTR8]] -// SANITIZE-WITHOUT-ATTR-NEXT: unreachable +// SANITIZE-WITHOUT-ATTR: cont1: +// SANITIZE-WITHOUT-ATTR-NEXT: ret i32 undef // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test15( // NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR1]] { @@ -1420,36 +1413,36 @@ struct tests_foo { // SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test24( // SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[VAR]], i64 40 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[VAR]], i64 40 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[ARRAYIDX]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = icmp ugt i32 [[DOTCOUNTED_BY_LOAD]], 10 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT4:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB28:[0-9]+]], i64 10) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB28:[0-9]+]], i64 10) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont4: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i8, ptr [[VAR]], i64 84 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw i8, ptr [[VAR]], i64 84 // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP1]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test24( // NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[VAR:%.*]]) local_unnamed_addr #[[ATTR2]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[VAR]], i64 84 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[VAR]], i64 84 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP0]] // // SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test24( // SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[VAR]], i64 84 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[VAR]], i64 84 // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4, !tbaa [[TBAA2]] // SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP0]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local i32 @test24( // NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[VAR:%.*]]) local_unnamed_addr #[[ATTR6:[0-9]+]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[VAR]], i64 84 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr [[VAR]], i64 84 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP0]] // @@ -1466,10 +1459,10 @@ int test24(int c, struct tests_foo *var) { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ugt i32 [[DOTCOUNTED_BY_LOAD]], 10 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB29:[0-9]+]], i64 10) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB29:[0-9]+]], i64 10) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont5: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 44 +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 44 // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP2]] // @@ -1477,7 +1470,7 @@ int test24(int c, struct tests_foo *var) { // NO-SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[VAR:%.*]]) local_unnamed_addr #[[ATTR8:[0-9]+]] { // NO-SANITIZE-WITH-ATTR-NEXT: entry: // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !tbaa [[TBAA14:![0-9]+]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 44 +// NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 44 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP1]] // @@ -1485,7 +1478,7 @@ int test24(int c, struct tests_foo *var) { // SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[VAR:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !tbaa [[TBAA17:![0-9]+]] -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 44 +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 44 // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP1]] // @@ -1493,7 +1486,7 @@ int test24(int c, struct tests_foo *var) { // NO-SANITIZE-WITHOUT-ATTR-SAME: i32 noundef [[C:%.*]], ptr nocapture noundef readonly [[VAR:%.*]]) local_unnamed_addr #[[ATTR7:[0-9]+]] { // NO-SANITIZE-WITHOUT-ATTR-NEXT: entry: // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VAR]], align 8, !tbaa [[TBAA14:![0-9]+]] -// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 44 +// NO-SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 44 // NO-SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // NO-SANITIZE-WITHOUT-ATTR-NEXT: ret i32 [[TMP1]] // @@ -1511,18 +1504,18 @@ struct test26_foo { // SANITIZE-WITH-ATTR-LABEL: define dso_local i32 @test26( // SANITIZE-WITH-ATTR-SAME: i32 noundef [[C:%.*]], ptr noundef [[FOO:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: -// SANITIZE-WITH-ATTR-NEXT: [[S:%.*]] = getelementptr inbounds i8, ptr [[FOO]], i64 4 +// SANITIZE-WITH-ATTR-NEXT: [[S:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[C]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[S]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT5:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB30:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB30:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont5: // SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[FOO]], i64 8 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP2]] // @@ -1583,17 +1576,17 @@ struct test27_foo { // SANITIZE-WITH-ATTR-SAME: ptr noundef [[P:%.*]], i32 noundef [[I:%.*]], i32 noundef [[J:%.*]]) local_unnamed_addr #[[ATTR0]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 12 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 12 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP0]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP1]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB32:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB32:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: // SANITIZE-WITH-ATTR-NEXT: [[ENTRIES:%.*]] = getelementptr inbounds nuw i8, ptr [[P]], i64 24 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x ptr], ptr [[ENTRIES]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x ptr], ptr [[ENTRIES]], i64 0, i64 [[IDXPROM]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA19:![0-9]+]] // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM4:%.*]] = sext i32 [[J]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [[STRUCT_TEST27_BAR:%.*]], ptr [[TMP2]], i64 [[IDXPROM4]] @@ -1649,17 +1642,17 @@ struct test28_foo { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = load ptr, ptr [[TMP0]], align 8, !tbaa [[TBAA21]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[TMP1]], align 8, !tbaa [[TBAA21]] // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[I]] to i64 -// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOTCOUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOTCOUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[DOTCOUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[IDXPROM]], [[TMP3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT17:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB34:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB34:[0-9]+]], i64 [[IDXPROM]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont17: // SANITIZE-WITH-ATTR-NEXT: [[ARR:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARR]], i64 0, i64 [[IDXPROM]] // SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA4]] // SANITIZE-WITH-ATTR-NEXT: ret i32 [[TMP5]] // @@ -1717,23 +1710,23 @@ struct annotated_struct_array { // SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[IDX1]] to i64 // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP0]], label [[CONT3:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB36:[0-9]+]], i64 [[TMP1]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB36:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont3: -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN]], i64 0, i64 [[TMP1]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [10 x ptr], ptr [[ANN]], i64 0, i64 [[TMP1]] // SANITIZE-WITH-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA23:![0-9]+]] -// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP2]], i64 8 +// SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 8 // SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // SANITIZE-WITH-ATTR-NEXT: [[IDXPROM15:%.*]] = sext i32 [[IDX2]] to i64 // SANITIZE-WITH-ATTR-NEXT: [[TMP3:%.*]] = zext i32 [[DOT_COUNTED_BY_LOAD]] to i64, !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: [[TMP4:%.*]] = icmp ult i64 [[IDXPROM15]], [[TMP3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: br i1 [[TMP4]], label [[CONT20:%.*]], label [[HANDLER_OUT_OF_BOUNDS16:%.*]], !prof [[PROF3]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR: handler.out_of_bounds16: -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB37:[0-9]+]], i64 [[IDXPROM15]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB37:[0-9]+]], i64 [[IDXPROM15]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // SANITIZE-WITH-ATTR: cont20: // SANITIZE-WITH-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12 -// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM15]] +// SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX18:%.*]] = getelementptr inbounds nuw [0 x i32], ptr [[ARRAY]], i64 0, i64 [[IDXPROM15]] // SANITIZE-WITH-ATTR-NEXT: [[TMP5:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) // SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[TMP5]], 2 // SANITIZE-WITH-ATTR-NEXT: store i32 [[CONV]], ptr [[ARRAYIDX18]], align 4, !tbaa [[TBAA4]] @@ -1745,7 +1738,7 @@ struct annotated_struct_array { // NO-SANITIZE-WITH-ATTR-NEXT: [[IDXPROM:%.*]] = sext i32 [[IDX1]] to i64 // NO-SANITIZE-WITH-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN]], i64 0, i64 [[IDXPROM]] // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA20:![0-9]+]] -// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds i8, ptr [[TMP0]], i64 8 +// NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_GEP:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP0]], i64 8 // NO-SANITIZE-WITH-ATTR-NEXT: [[DOT_COUNTED_BY_LOAD:%.*]] = load i32, ptr [[DOT_COUNTED_BY_GEP]], align 4 // NO-SANITIZE-WITH-ATTR-NEXT: [[TMP1:%.*]] = tail call i32 @llvm.smax.i32(i32 [[DOT_COUNTED_BY_LOAD]], i32 0) // NO-SANITIZE-WITH-ATTR-NEXT: [[CONV:%.*]] = shl i32 [[TMP1]], 2 @@ -1762,10 +1755,10 @@ struct annotated_struct_array { // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP1:%.*]] = zext i32 [[IDX1]] to i64 // SANITIZE-WITHOUT-ATTR-NEXT: br i1 [[TMP0]], label [[CONT21:%.*]], label [[HANDLER_OUT_OF_BOUNDS:%.*]], !prof [[PROF8]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: handler.out_of_bounds: -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 [[TMP1]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB13:[0-9]+]], i64 [[TMP1]]) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR: cont21: -// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [10 x ptr], ptr [[ANN]], i64 0, i64 [[TMP1]] +// SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw [10 x ptr], ptr [[ANN]], i64 0, i64 [[TMP1]] // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP2:%.*]] = load ptr, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA23:![0-9]+]] // SANITIZE-WITHOUT-ATTR-NEXT: [[ARRAY:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP2]], i64 12 // SANITIZE-WITHOUT-ATTR-NEXT: [[IDXPROM18:%.*]] = sext i32 [[IDX2]] to i64 @@ -1804,7 +1797,7 @@ struct test30_struct { // SANITIZE-WITH-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR4]] { // SANITIZE-WITH-ATTR-NEXT: entry: // SANITIZE-WITH-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[IDX]] to i64, !nosanitize [[META2]] -// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB39:[0-9]+]], i64 [[TMP0]]) #[[ATTR9]], !nosanitize [[META2]] +// SANITIZE-WITH-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB39:[0-9]+]], i64 [[TMP0]]) #[[ATTR8]], !nosanitize [[META2]] // SANITIZE-WITH-ATTR-NEXT: unreachable, !nosanitize [[META2]] // // NO-SANITIZE-WITH-ATTR-LABEL: define dso_local void @test30( @@ -1820,7 +1813,7 @@ struct test30_struct { // SANITIZE-WITHOUT-ATTR-SAME: ptr noundef [[PTR:%.*]], i32 noundef [[IDX:%.*]]) local_unnamed_addr #[[ATTR3]] { // SANITIZE-WITHOUT-ATTR-NEXT: entry: // SANITIZE-WITHOUT-ATTR-NEXT: [[TMP0:%.*]] = zext i32 [[IDX]] to i64, !nosanitize [[META9]] -// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP0]]) #[[ATTR8]], !nosanitize [[META9]] +// SANITIZE-WITHOUT-ATTR-NEXT: tail call void @__ubsan_handle_out_of_bounds_abort(ptr nonnull @[[GLOB15:[0-9]+]], i64 [[TMP0]]) #[[ATTR7]], !nosanitize [[META9]] // SANITIZE-WITHOUT-ATTR-NEXT: unreachable, !nosanitize [[META9]] // // NO-SANITIZE-WITHOUT-ATTR-LABEL: define dso_local void @test30( diff --git a/clang/test/CodeGen/attr-target-clones-aarch64.c b/clang/test/CodeGen/attr-target-clones-aarch64.c index 961279424754d..6b7acbbd4fc59 100644 --- a/clang/test/CodeGen/attr-target-clones-aarch64.c +++ b/clang/test/CodeGen/attr-target-clones-aarch64.c @@ -64,16 +64,16 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 32896 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 32896 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 33664 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 33664 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: // CHECK-NEXT: ret ptr @ftc._MaesMlse // CHECK: resolver_else: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 68719476736 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 68719476736 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 69793284352 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 69793284352 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK: resolver_return1: @@ -100,16 +100,16 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 17592186048512 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 17592186048512 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 17592186049280 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 17592186049280 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: // CHECK-NEXT: ret ptr @ftc_def._MmemtagMsha2 // CHECK: resolver_else: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 4096 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 4096 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 4864 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 4864 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK: resolver_return1: @@ -129,8 +129,8 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4096 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4096 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4864 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4864 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: @@ -157,8 +157,8 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1040 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1040 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1808 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1808 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: @@ -310,16 +310,16 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 549757911040 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 549757911040 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 619551195904 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 619551195904 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: // CHECK-NEXT: ret ptr @ftc_inline2._MfcmaMsve2-bitperm // CHECK: resolver_else: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 65536 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 65536 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 65792 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 65792 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK: resolver_return1: @@ -360,8 +360,8 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 18014673387388928 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 18014673387388928 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 18014743180706560 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 18014743180706560 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: @@ -376,8 +376,8 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-NEXT: ret ptr @ftc_inline1._MpredresMrcpc // CHECK: resolver_else2: // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 513 -// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 513 +// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 769 +// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 769 // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] // CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] // CHECK: resolver_return3: @@ -411,8 +411,8 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 70369817919488 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 70369817919488 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 70369817985280 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 70369817985280 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: @@ -521,16 +521,16 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI-NEXT: resolver_entry: // CHECK-MTE-BTI-NEXT: call void @__init_cpu_features_resolver() // CHECK-MTE-BTI-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 32896 -// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 32896 +// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 33664 +// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 33664 // CHECK-MTE-BTI-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-MTE-BTI-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK-MTE-BTI: resolver_return: // CHECK-MTE-BTI-NEXT: ret ptr @ftc._MaesMlse // CHECK-MTE-BTI: resolver_else: // CHECK-MTE-BTI-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-MTE-BTI-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 68719476736 -// CHECK-MTE-BTI-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 68719476736 +// CHECK-MTE-BTI-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 69793284352 +// CHECK-MTE-BTI-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 69793284352 // CHECK-MTE-BTI-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-MTE-BTI-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK-MTE-BTI: resolver_return1: @@ -557,16 +557,16 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI-NEXT: resolver_entry: // CHECK-MTE-BTI-NEXT: call void @__init_cpu_features_resolver() // CHECK-MTE-BTI-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 17592186048512 -// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 17592186048512 +// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 17592186049280 +// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 17592186049280 // CHECK-MTE-BTI-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-MTE-BTI-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK-MTE-BTI: resolver_return: // CHECK-MTE-BTI-NEXT: ret ptr @ftc_def._MmemtagMsha2 // CHECK-MTE-BTI: resolver_else: // CHECK-MTE-BTI-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-MTE-BTI-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 4096 -// CHECK-MTE-BTI-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 4096 +// CHECK-MTE-BTI-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 4864 +// CHECK-MTE-BTI-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 4864 // CHECK-MTE-BTI-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-MTE-BTI-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK-MTE-BTI: resolver_return1: @@ -586,8 +586,8 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI-NEXT: resolver_entry: // CHECK-MTE-BTI-NEXT: call void @__init_cpu_features_resolver() // CHECK-MTE-BTI-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4096 -// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4096 +// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4864 +// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4864 // CHECK-MTE-BTI-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-MTE-BTI-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK-MTE-BTI: resolver_return: @@ -614,8 +614,8 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI-NEXT: resolver_entry: // CHECK-MTE-BTI-NEXT: call void @__init_cpu_features_resolver() // CHECK-MTE-BTI-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1040 -// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1040 +// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1808 +// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1808 // CHECK-MTE-BTI-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-MTE-BTI-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK-MTE-BTI: resolver_return: @@ -767,16 +767,16 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI-NEXT: resolver_entry: // CHECK-MTE-BTI-NEXT: call void @__init_cpu_features_resolver() // CHECK-MTE-BTI-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 549757911040 -// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 549757911040 +// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 619551195904 +// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 619551195904 // CHECK-MTE-BTI-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-MTE-BTI-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK-MTE-BTI: resolver_return: // CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline2._MfcmaMsve2-bitperm // CHECK-MTE-BTI: resolver_else: // CHECK-MTE-BTI-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-MTE-BTI-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 65536 -// CHECK-MTE-BTI-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 65536 +// CHECK-MTE-BTI-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 65792 +// CHECK-MTE-BTI-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 65792 // CHECK-MTE-BTI-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-MTE-BTI-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK-MTE-BTI: resolver_return1: @@ -817,8 +817,8 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI-NEXT: resolver_entry: // CHECK-MTE-BTI-NEXT: call void @__init_cpu_features_resolver() // CHECK-MTE-BTI-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 18014673387388928 -// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 18014673387388928 +// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 18014743180706560 +// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 18014743180706560 // CHECK-MTE-BTI-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-MTE-BTI-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK-MTE-BTI: resolver_return: @@ -833,8 +833,8 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI-NEXT: ret ptr @ftc_inline1._MpredresMrcpc // CHECK-MTE-BTI: resolver_else2: // CHECK-MTE-BTI-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-MTE-BTI-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 513 -// CHECK-MTE-BTI-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 513 +// CHECK-MTE-BTI-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 769 +// CHECK-MTE-BTI-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 769 // CHECK-MTE-BTI-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] // CHECK-MTE-BTI-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] // CHECK-MTE-BTI: resolver_return3: @@ -868,8 +868,8 @@ inline int __attribute__((target_clones("fp16", "sve2-bitperm+fcma", "default")) // CHECK-MTE-BTI-NEXT: resolver_entry: // CHECK-MTE-BTI-NEXT: call void @__init_cpu_features_resolver() // CHECK-MTE-BTI-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 70369817919488 -// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 70369817919488 +// CHECK-MTE-BTI-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 70369817985280 +// CHECK-MTE-BTI-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 70369817985280 // CHECK-MTE-BTI-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-MTE-BTI-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK-MTE-BTI: resolver_return: diff --git a/clang/test/CodeGen/attr-target-version.c b/clang/test/CodeGen/attr-target-version.c index 4194ce2687050..428e7937d8d39 100644 --- a/clang/test/CodeGen/attr-target-version.c +++ b/clang/test/CodeGen/attr-target-version.c @@ -460,24 +460,24 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 11 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 11 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 66315 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 66315 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: // CHECK-NEXT: ret ptr @fmv._MflagmMfp16fmlMrng // CHECK: resolver_else: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 72057594037927940 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 72057594037927940 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 72061992218723078 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 72061992218723078 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK: resolver_return1: // CHECK-NEXT: ret ptr @fmv._Mflagm2Msme-i16i64 // CHECK: resolver_else2: // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 9007199254741008 -// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 9007199254741008 +// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 9007199254741776 +// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 9007199254741776 // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] // CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] // CHECK: resolver_return3: @@ -492,32 +492,32 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: ret ptr @fmv._McrcMls64 // CHECK: resolver_else6: // CHECK-NEXT: [[TMP16:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP17:%.*]] = and i64 [[TMP16]], 17592186044424 -// CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[TMP17]], 17592186044424 +// CHECK-NEXT: [[TMP17:%.*]] = and i64 [[TMP16]], 17592186110728 +// CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[TMP17]], 17592186110728 // CHECK-NEXT: [[TMP19:%.*]] = and i1 true, [[TMP18]] // CHECK-NEXT: br i1 [[TMP19]], label [[RESOLVER_RETURN7:%.*]], label [[RESOLVER_ELSE8:%.*]] // CHECK: resolver_return7: // CHECK-NEXT: ret ptr @fmv._Mfp16fmlMmemtag // CHECK: resolver_else8: // CHECK-NEXT: [[TMP20:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 33024 -// CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 33024 +// CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 33536 +// CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 33536 // CHECK-NEXT: [[TMP23:%.*]] = and i1 true, [[TMP22]] // CHECK-NEXT: br i1 [[TMP23]], label [[RESOLVER_RETURN9:%.*]], label [[RESOLVER_ELSE10:%.*]] // CHECK: resolver_return9: // CHECK-NEXT: ret ptr @fmv._MaesMfp // CHECK: resolver_else10: // CHECK-NEXT: [[TMP24:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP25:%.*]] = and i64 [[TMP24]], 4224 -// CHECK-NEXT: [[TMP26:%.*]] = icmp eq i64 [[TMP25]], 4224 +// CHECK-NEXT: [[TMP25:%.*]] = and i64 [[TMP24]], 4992 +// CHECK-NEXT: [[TMP26:%.*]] = icmp eq i64 [[TMP25]], 4992 // CHECK-NEXT: [[TMP27:%.*]] = and i1 true, [[TMP26]] // CHECK-NEXT: br i1 [[TMP27]], label [[RESOLVER_RETURN11:%.*]], label [[RESOLVER_ELSE12:%.*]] // CHECK: resolver_return11: // CHECK-NEXT: ret ptr @fmv._MlseMsha2 // CHECK: resolver_else12: // CHECK-NEXT: [[TMP28:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP29:%.*]] = and i64 [[TMP28]], 144115188075855872 -// CHECK-NEXT: [[TMP30:%.*]] = icmp eq i64 [[TMP29]], 144115188075855872 +// CHECK-NEXT: [[TMP29:%.*]] = and i64 [[TMP28]], 144119586256651008 +// CHECK-NEXT: [[TMP30:%.*]] = icmp eq i64 [[TMP29]], 144119586256651008 // CHECK-NEXT: [[TMP31:%.*]] = and i1 true, [[TMP30]] // CHECK-NEXT: br i1 [[TMP31]], label [[RESOLVER_RETURN13:%.*]], label [[RESOLVER_ELSE14:%.*]] // CHECK: resolver_return13: @@ -538,8 +538,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 9007199254741504 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 9007199254741504 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 9007199254741760 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 9007199254741760 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: @@ -560,16 +560,16 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 66048 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 66048 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 66304 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 66304 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: // CHECK-NEXT: ret ptr @fmv_two._Mfp16Msimd // CHECK: resolver_else: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 512 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 512 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 768 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 768 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK: resolver_return1: @@ -765,128 +765,128 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4398048673856 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4398048673856 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4398182892352 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 4398182892352 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: // CHECK-NEXT: ret ptr @fmv_inline._MfcmaMfp16MrdmMsme // CHECK: resolver_else: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 864708720641179648 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 864708720641179648 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 864708720653762560 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 864708720653762560 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK: resolver_return1: // CHECK-NEXT: ret ptr @fmv_inline._MmemtagMmopsMrcpc3 // CHECK: resolver_else2: // CHECK-NEXT: [[TMP8:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 893353197568 -// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 893353197568 +// CHECK-NEXT: [[TMP9:%.*]] = and i64 [[TMP8]], 894427038464 +// CHECK-NEXT: [[TMP10:%.*]] = icmp eq i64 [[TMP9]], 894427038464 // CHECK-NEXT: [[TMP11:%.*]] = and i1 true, [[TMP10]] // CHECK-NEXT: br i1 [[TMP11]], label [[RESOLVER_RETURN3:%.*]], label [[RESOLVER_ELSE4:%.*]] // CHECK: resolver_return3: // CHECK-NEXT: ret ptr @fmv_inline._Msve2Msve2-aesMsve2-bitperm // CHECK: resolver_else4: // CHECK-NEXT: [[TMP12:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 34359775232 -// CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 34359775232 +// CHECK-NEXT: [[TMP13:%.*]] = and i64 [[TMP12]], 35433583360 +// CHECK-NEXT: [[TMP14:%.*]] = icmp eq i64 [[TMP13]], 35433583360 // CHECK-NEXT: [[TMP15:%.*]] = and i1 true, [[TMP14]] // CHECK-NEXT: br i1 [[TMP15]], label [[RESOLVER_RETURN5:%.*]], label [[RESOLVER_ELSE6:%.*]] // CHECK: resolver_return5: // CHECK-NEXT: ret ptr @fmv_inline._MaesMf64mmMsha2 // CHECK: resolver_else6: // CHECK-NEXT: [[TMP16:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP17:%.*]] = and i64 [[TMP16]], 17246986240 -// CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[TMP17]], 17246986240 +// CHECK-NEXT: [[TMP17:%.*]] = and i64 [[TMP16]], 18320798464 +// CHECK-NEXT: [[TMP18:%.*]] = icmp eq i64 [[TMP17]], 18320798464 // CHECK-NEXT: [[TMP19:%.*]] = and i1 true, [[TMP18]] // CHECK-NEXT: br i1 [[TMP19]], label [[RESOLVER_RETURN7:%.*]], label [[RESOLVER_ELSE8:%.*]] // CHECK: resolver_return7: // CHECK-NEXT: ret ptr @fmv_inline._Mf32mmMi8mmMsha3 // CHECK: resolver_else8: // CHECK-NEXT: [[TMP20:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 19791209299968 -// CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 19791209299968 +// CHECK-NEXT: [[TMP21:%.*]] = and i64 [[TMP20]], 19861002584864 +// CHECK-NEXT: [[TMP22:%.*]] = icmp eq i64 [[TMP21]], 19861002584864 // CHECK-NEXT: [[TMP23:%.*]] = and i1 true, [[TMP22]] // CHECK-NEXT: br i1 [[TMP23]], label [[RESOLVER_RETURN9:%.*]], label [[RESOLVER_ELSE10:%.*]] // CHECK: resolver_return9: // CHECK-NEXT: ret ptr @fmv_inline._MmemtagMsve2-sm4 // CHECK: resolver_else10: // CHECK-NEXT: [[TMP24:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP25:%.*]] = and i64 [[TMP24]], 1374389534720 -// CHECK-NEXT: [[TMP26:%.*]] = icmp eq i64 [[TMP25]], 1374389534720 +// CHECK-NEXT: [[TMP25:%.*]] = and i64 [[TMP24]], 1444182864640 +// CHECK-NEXT: [[TMP26:%.*]] = icmp eq i64 [[TMP25]], 1444182864640 // CHECK-NEXT: [[TMP27:%.*]] = and i1 true, [[TMP26]] // CHECK-NEXT: br i1 [[TMP27]], label [[RESOLVER_RETURN11:%.*]], label [[RESOLVER_ELSE12:%.*]] // CHECK: resolver_return11: // CHECK-NEXT: ret ptr @fmv_inline._Msve2-aesMsve2-sha3 // CHECK: resolver_else12: // CHECK-NEXT: [[TMP28:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP29:%.*]] = and i64 [[TMP28]], 1207959552 -// CHECK-NEXT: [[TMP30:%.*]] = icmp eq i64 [[TMP29]], 1207959552 +// CHECK-NEXT: [[TMP29:%.*]] = and i64 [[TMP28]], 1208025856 +// CHECK-NEXT: [[TMP30:%.*]] = icmp eq i64 [[TMP29]], 1208025856 // CHECK-NEXT: [[TMP31:%.*]] = and i1 true, [[TMP30]] // CHECK-NEXT: br i1 [[TMP31]], label [[RESOLVER_RETURN13:%.*]], label [[RESOLVER_ELSE14:%.*]] // CHECK: resolver_return13: // CHECK-NEXT: ret ptr @fmv_inline._Mbf16Msve // CHECK: resolver_else14: // CHECK-NEXT: [[TMP32:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP33:%.*]] = and i64 [[TMP32]], 134348800 -// CHECK-NEXT: [[TMP34:%.*]] = icmp eq i64 [[TMP33]], 134348800 +// CHECK-NEXT: [[TMP33:%.*]] = and i64 [[TMP32]], 134349568 +// CHECK-NEXT: [[TMP34:%.*]] = icmp eq i64 [[TMP33]], 134349568 // CHECK-NEXT: [[TMP35:%.*]] = and i1 true, [[TMP34]] // CHECK-NEXT: br i1 [[TMP35]], label [[RESOLVER_RETURN15:%.*]], label [[RESOLVER_ELSE16:%.*]] // CHECK: resolver_return15: // CHECK-NEXT: ret ptr @fmv_inline._Mbf16Mdit // CHECK: resolver_else16: // CHECK-NEXT: [[TMP36:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP37:%.*]] = and i64 [[TMP36]], 20971520 -// CHECK-NEXT: [[TMP38:%.*]] = icmp eq i64 [[TMP37]], 20971520 +// CHECK-NEXT: [[TMP37:%.*]] = and i64 [[TMP36]], 20971776 +// CHECK-NEXT: [[TMP38:%.*]] = icmp eq i64 [[TMP37]], 20971776 // CHECK-NEXT: [[TMP39:%.*]] = and i1 true, [[TMP38]] // CHECK-NEXT: br i1 [[TMP39]], label [[RESOLVER_RETURN17:%.*]], label [[RESOLVER_ELSE18:%.*]] // CHECK: resolver_return17: // CHECK-NEXT: ret ptr @fmv_inline._MfrinttsMrcpc // CHECK: resolver_else18: // CHECK-NEXT: [[TMP40:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP41:%.*]] = and i64 [[TMP40]], 8650752 -// CHECK-NEXT: [[TMP42:%.*]] = icmp eq i64 [[TMP41]], 8650752 +// CHECK-NEXT: [[TMP41:%.*]] = and i64 [[TMP40]], 12845056 +// CHECK-NEXT: [[TMP42:%.*]] = icmp eq i64 [[TMP41]], 12845056 // CHECK-NEXT: [[TMP43:%.*]] = and i1 true, [[TMP42]] // CHECK-NEXT: br i1 [[TMP43]], label [[RESOLVER_RETURN19:%.*]], label [[RESOLVER_ELSE20:%.*]] // CHECK: resolver_return19: // CHECK-NEXT: ret ptr @fmv_inline._MdpbMrcpc2 // CHECK: resolver_else20: // CHECK-NEXT: [[TMP44:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP45:%.*]] = and i64 [[TMP44]], 1572864 -// CHECK-NEXT: [[TMP46:%.*]] = icmp eq i64 [[TMP45]], 1572864 +// CHECK-NEXT: [[TMP45:%.*]] = and i64 [[TMP44]], 1835264 +// CHECK-NEXT: [[TMP46:%.*]] = icmp eq i64 [[TMP45]], 1835264 // CHECK-NEXT: [[TMP47:%.*]] = and i1 true, [[TMP46]] // CHECK-NEXT: br i1 [[TMP47]], label [[RESOLVER_RETURN21:%.*]], label [[RESOLVER_ELSE22:%.*]] // CHECK: resolver_return21: // CHECK-NEXT: ret ptr @fmv_inline._Mdpb2Mjscvt // CHECK: resolver_else22: // CHECK-NEXT: [[TMP48:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP49:%.*]] = and i64 [[TMP48]], 520 -// CHECK-NEXT: [[TMP50:%.*]] = icmp eq i64 [[TMP49]], 520 +// CHECK-NEXT: [[TMP49:%.*]] = and i64 [[TMP48]], 66312 +// CHECK-NEXT: [[TMP50:%.*]] = icmp eq i64 [[TMP49]], 66312 // CHECK-NEXT: [[TMP51:%.*]] = and i1 true, [[TMP50]] // CHECK-NEXT: br i1 [[TMP51]], label [[RESOLVER_RETURN23:%.*]], label [[RESOLVER_ELSE24:%.*]] // CHECK: resolver_return23: // CHECK-NEXT: ret ptr @fmv_inline._Mfp16fmlMsimd // CHECK: resolver_else24: // CHECK-NEXT: [[TMP52:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP53:%.*]] = and i64 [[TMP52]], 32784 -// CHECK-NEXT: [[TMP54:%.*]] = icmp eq i64 [[TMP53]], 32784 +// CHECK-NEXT: [[TMP53:%.*]] = and i64 [[TMP52]], 33552 +// CHECK-NEXT: [[TMP54:%.*]] = icmp eq i64 [[TMP53]], 33552 // CHECK-NEXT: [[TMP55:%.*]] = and i1 true, [[TMP54]] // CHECK-NEXT: br i1 [[TMP55]], label [[RESOLVER_RETURN25:%.*]], label [[RESOLVER_ELSE26:%.*]] // CHECK: resolver_return25: // CHECK-NEXT: ret ptr @fmv_inline._MaesMdotprod // CHECK: resolver_else26: // CHECK-NEXT: [[TMP56:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP57:%.*]] = and i64 [[TMP56]], 192 -// CHECK-NEXT: [[TMP58:%.*]] = icmp eq i64 [[TMP57]], 192 +// CHECK-NEXT: [[TMP57:%.*]] = and i64 [[TMP56]], 960 +// CHECK-NEXT: [[TMP58:%.*]] = icmp eq i64 [[TMP57]], 960 // CHECK-NEXT: [[TMP59:%.*]] = and i1 true, [[TMP58]] // CHECK-NEXT: br i1 [[TMP59]], label [[RESOLVER_RETURN27:%.*]], label [[RESOLVER_ELSE28:%.*]] // CHECK: resolver_return27: // CHECK-NEXT: ret ptr @fmv_inline._MlseMrdm // CHECK: resolver_else28: // CHECK-NEXT: [[TMP60:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP61:%.*]] = and i64 [[TMP60]], 288 -// CHECK-NEXT: [[TMP62:%.*]] = icmp eq i64 [[TMP61]], 288 +// CHECK-NEXT: [[TMP61:%.*]] = and i64 [[TMP60]], 800 +// CHECK-NEXT: [[TMP62:%.*]] = icmp eq i64 [[TMP61]], 800 // CHECK-NEXT: [[TMP63:%.*]] = and i1 true, [[TMP62]] // CHECK-NEXT: br i1 [[TMP63]], label [[RESOLVER_RETURN29:%.*]], label [[RESOLVER_ELSE30:%.*]] // CHECK: resolver_return29: @@ -899,8 +899,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073807616 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073807616 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: @@ -913,8 +913,8 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65536 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65536 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65792 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65792 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: @@ -941,16 +941,16 @@ int caller(void) { return used_def_without_default_decl() + used_decl_without_de // CHECK-NEXT: resolver_entry: // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1048576 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048576 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1048832 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1048832 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label [[RESOLVER_RETURN:%.*]], label [[RESOLVER_ELSE:%.*]] // CHECK: resolver_return: // CHECK-NEXT: ret ptr @default_def_with_version_decls._Mjscvt // CHECK: resolver_else: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 64 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 64 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 832 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 832 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label [[RESOLVER_RETURN1:%.*]], label [[RESOLVER_ELSE2:%.*]] // CHECK: resolver_return1: diff --git a/clang/test/CodeGen/builtins-elementwise-math.c b/clang/test/CodeGen/builtins-elementwise-math.c index 82f82dd1ed794..7f6b5f26eb930 100644 --- a/clang/test/CodeGen/builtins-elementwise-math.c +++ b/clang/test/CodeGen/builtins-elementwise-math.c @@ -112,7 +112,7 @@ void test_builtin_elementwise_add_sat(float f1, float f2, double d1, double d2, // CHECK-NEXT: call i32 @llvm.sadd.sat.i32(i32 [[IAS1]], i32 [[B]]) int_as_one = __builtin_elementwise_add_sat(int_as_one, b); - // CHECK: call i32 @llvm.sadd.sat.i32(i32 1, i32 97) + // CHECK: store i64 98, ptr %i1.addr, align 8 i1 = __builtin_elementwise_add_sat(1, 'a'); } @@ -165,7 +165,7 @@ void test_builtin_elementwise_sub_sat(float f1, float f2, double d1, double d2, // CHECK-NEXT: call i32 @llvm.ssub.sat.i32(i32 [[IAS1]], i32 [[B]]) int_as_one = __builtin_elementwise_sub_sat(int_as_one, b); - // CHECK: call i32 @llvm.ssub.sat.i32(i32 1, i32 97) + // CHECK: store i64 -96, ptr %i1.addr, align 8 i1 = __builtin_elementwise_sub_sat(1, 'a'); } diff --git a/clang/test/CodeGen/ignore-overflow-pattern.c b/clang/test/CodeGen/ignore-overflow-pattern.c index c4a9d07b07aaa..4e5ed82d7967e 100644 --- a/clang/test/CodeGen/ignore-overflow-pattern.c +++ b/clang/test/CodeGen/ignore-overflow-pattern.c @@ -21,7 +21,10 @@ // unsigned negation, for example: // unsigned long A = -1UL; +// Skip over parts of the IR containing this file's name. +// CHECK: source_filename = {{.*}} +// Ensure we don't see anything about handling overflow before the tests below. // CHECK-NOT: handle{{.*}}overflow extern unsigned a, b, c; diff --git a/clang/test/CodeGen/math-libcalls-tbaa.c b/clang/test/CodeGen/math-libcalls-tbaa.c index 9c86eea67d14d..17a93ed2aed2d 100644 --- a/clang/test/CodeGen/math-libcalls-tbaa.c +++ b/clang/test/CodeGen/math-libcalls-tbaa.c @@ -16,7 +16,7 @@ float crealf(float _Complex); // CHECK-LABEL: define dso_local float @test_expf( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[NUM]], i64 40 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2:![0-9]+]] // CHECK-NEXT: [[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) #[[ATTR9:[0-9]+]], !tbaa [[TBAA6:![0-9]+]] // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] @@ -31,7 +31,7 @@ float test_expf (float num[]) { // CHECK-LABEL: define dso_local float @test_builtin_expf( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 40 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[NUM]], i64 40 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: [[CALL:%.*]] = tail call float @expf(float noundef [[TMP0]]) #[[ATTR9]], !tbaa [[TBAA6]] // CHECK-NEXT: [[MUL:%.*]] = fmul float [[TMP0]], [[CALL]] @@ -48,7 +48,7 @@ float test_builtin_expf (float num[]) { // CHECK-LABEL: define dso_local double @test_fabs( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 80 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[NUM]], i64 80 // CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8:![0-9]+]] // CHECK-NEXT: [[TMP1:%.*]] = tail call double @llvm.fabs.f64(double [[TMP0]]) // CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[TMP1]] @@ -63,7 +63,7 @@ double test_fabs (double num[]) { // CHECK-LABEL: define dso_local double @test_remainder( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]], double noundef [[A:%.*]]) local_unnamed_addr #[[ATTR0]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 80 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[NUM]], i64 80 // CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8]] // CHECK-NEXT: [[CALL:%.*]] = tail call double @remainder(double noundef [[TMP0]], double noundef [[A]]) #[[ATTR9]], !tbaa [[TBAA6]] // CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[CALL]] @@ -83,7 +83,7 @@ double test_remainder (double num[], double a) { // CHECK-NEXT: [[ENTRY:.*:]] // CHECK-NEXT: [[E:%.*]] = alloca i32, align 4 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[E]]) #[[ATTR9]] -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 16 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[NUM]], i64 16 // CHECK-NEXT: [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8, !tbaa [[TBAA8]] // CHECK-NEXT: [[CALL:%.*]] = call double @frexp(double noundef [[TMP0]], ptr noundef nonnull [[E]]) #[[ATTR9]] // CHECK-NEXT: [[MUL:%.*]] = fmul double [[TMP0]], [[CALL]] @@ -107,7 +107,7 @@ double test_frexp (double num[]) { // CHECK-NEXT: [[COS:%.*]] = alloca float, align 4 // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[SIN]]) #[[ATTR9]] // CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 4, ptr nonnull [[COS]]) #[[ATTR9]] -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 8 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[NUM]], i64 8 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: call void @sincos(float noundef [[TMP0]], ptr noundef nonnull [[SIN]], ptr noundef nonnull [[COS]]) #[[ATTR9]] // CHECK-NEXT: [[TMP1:%.*]] = load float, ptr [[SIN]], align 4, !tbaa [[TBAA2]] @@ -130,7 +130,7 @@ float test_sincos (float num[]) { // CHECK-LABEL: define dso_local float @test_cacoshf( // CHECK-SAME: ptr nocapture noundef readonly [[NUM:%.*]]) local_unnamed_addr #[[ATTR7]] { // CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i8, ptr [[NUM]], i64 8 +// CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds nuw i8, ptr [[NUM]], i64 8 // CHECK-NEXT: [[TMP0:%.*]] = load float, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: [[DOTFCA_0_INSERT:%.*]] = insertvalue [2 x float] poison, float [[TMP0]], 0 // CHECK-NEXT: [[DOTFCA_1_INSERT:%.*]] = insertvalue [2 x float] [[DOTFCA_0_INSERT]], float 0.000000e+00, 1 diff --git a/clang/test/CodeGen/ptrauth-module-flags.c b/clang/test/CodeGen/ptrauth-module-flags.c index 5a7e9a7c2a36f..e441d52cb7c62 100644 --- a/clang/test/CodeGen/ptrauth-module-flags.c +++ b/clang/test/CodeGen/ptrauth-module-flags.c @@ -1,8 +1,13 @@ // RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s --check-prefix=OFF // RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-elf-got -emit-llvm %s -o - | FileCheck %s --check-prefix=ELFGOT +// RUN: %clang_cc1 -triple aarch64-linux-gnu -fptrauth-calls -emit-llvm %s -o - | FileCheck %s --check-prefix=PERSONALITY // ELFGOT: !llvm.module.flags = !{ // ELFGOT-SAME: !1 // ELFGOT: !1 = !{i32 8, !"ptrauth-elf-got", i32 1} +// PERSONALITY: !llvm.module.flags = !{ +// PERSONALITY-SAME: !1 +// PERSONALITY: !1 = !{i32 8, !"ptrauth-sign-personality", i32 1} + // OFF-NOT: "ptrauth- diff --git a/clang/test/CodeGen/target-data.c b/clang/test/CodeGen/target-data.c index cb89fad941c83..71eb849433ed4 100644 --- a/clang/test/CodeGen/target-data.c +++ b/clang/test/CodeGen/target-data.c @@ -88,7 +88,7 @@ // RUN: %clang_cc1 -triple powerpc64-lv2 -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PS3 -// PS3: target datalayout = "E-m:e-p:32:32-Fi64-i64:64-n32:64" +// PS3: target datalayout = "E-m:e-p:32:32-Fi64-i64:64-i128:128-n32:64" // RUN: %clang_cc1 -triple i686-nacl -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=I686-NACL @@ -108,11 +108,11 @@ // RUN: %clang_cc1 -triple wasm32-unknown-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=WEBASSEMBLY32 -// WEBASSEMBLY32: target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" +// WEBASSEMBLY32: target datalayout = "e-m:e-p:32:32-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20" // RUN: %clang_cc1 -triple wasm64-unknown-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=WEBASSEMBLY64 -// WEBASSEMBLY64: target datalayout = "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-n32:64-S128-ni:1:10:20" +// WEBASSEMBLY64: target datalayout = "e-m:e-p:64:64-p10:8:8-p20:8:8-i64:64-i128:128-n32:64-S128-ni:1:10:20" // RUN: %clang_cc1 -triple lanai-unknown-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=LANAI @@ -128,35 +128,35 @@ // RUN: %clang_cc1 -triple powerpc64-freebsd -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PPC64-FREEBSD -// PPC64-FREEBSD: target datalayout = "E-m:e-Fn32-i64:64-n32:64" +// PPC64-FREEBSD: target datalayout = "E-m:e-Fn32-i64:64-i128:128-n32:64" // RUN: %clang_cc1 -triple powerpc64le-freebsd -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PPC64LE-FREEBSD -// PPC64LE-FREEBSD: target datalayout = "e-m:e-Fn32-i64:64-n32:64" +// PPC64LE-FREEBSD: target datalayout = "e-m:e-Fn32-i64:64-i128:128-n32:64" // RUN: %clang_cc1 -triple powerpc64-linux -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PPC64-LINUX -// PPC64-LINUX: target datalayout = "E-m:e-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512" +// PPC64-LINUX: target datalayout = "E-m:e-Fi64-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512" // RUN: %clang_cc1 -triple powerpc64-linux -o - -emit-llvm -target-cpu future %s | \ // RUN: FileCheck %s -check-prefix=PPC64-FUTURE -// PPC64-FUTURE: target datalayout = "E-m:e-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512" +// PPC64-FUTURE: target datalayout = "E-m:e-Fi64-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512" // RUN: %clang_cc1 -triple powerpc64-linux -o - -emit-llvm -target-cpu pwr10 %s | \ // RUN: FileCheck %s -check-prefix=PPC64-P10 -// PPC64-P10: target datalayout = "E-m:e-Fi64-i64:64-n32:64-S128-v256:256:256-v512:512:512" +// PPC64-P10: target datalayout = "E-m:e-Fi64-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512" // RUN: %clang_cc1 -triple powerpc64le-linux -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=PPC64LE-LINUX -// PPC64LE-LINUX: target datalayout = "e-m:e-Fn32-i64:64-n32:64-S128-v256:256:256-v512:512:512" +// PPC64LE-LINUX: target datalayout = "e-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512" // RUN: %clang_cc1 -triple powerpc64le-linux -o - -emit-llvm -target-cpu future %s | \ // RUN: FileCheck %s -check-prefix=PPC64LE-FUTURE -// PPC64LE-FUTURE: target datalayout = "e-m:e-Fn32-i64:64-n32:64-S128-v256:256:256-v512:512:512" +// PPC64LE-FUTURE: target datalayout = "e-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512" // RUN: %clang_cc1 -triple powerpc64le-linux -o - -emit-llvm -target-cpu pwr10 %s | \ // RUN: FileCheck %s -check-prefix=PPC64LE-P10 -// PPC64LE-P10: target datalayout = "e-m:e-Fn32-i64:64-n32:64-S128-v256:256:256-v512:512:512" +// PPC64LE-P10: target datalayout = "e-m:e-Fn32-i64:64-i128:128-n32:64-S128-v256:256:256-v512:512:512" // RUN: %clang_cc1 -triple nvptx-unknown -o - -emit-llvm %s | \ // RUN: FileCheck %s -check-prefix=NVPTX diff --git a/clang/test/CodeGen/ubsan-trap-merge.c b/clang/test/CodeGen/ubsan-trap-merge.c index dccce0ce4c56b..412ec7b09744e 100644 --- a/clang/test/CodeGen/ubsan-trap-merge.c +++ b/clang/test/CodeGen/ubsan-trap-merge.c @@ -1,67 +1,168 @@ // NOTE: Assertions have mostly been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --version 5 // The most important assertion is the attributes at the end of the file, which -// shows that -ubsan-unique-traps attaches 'nomerge' to each ubsantrap intrinsic. +// shows whether -ubsan-unique-traps attaches 'nomerge' to each ubsan call. // -// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -fsanitize-trap=signed-integer-overflow -O3 -mllvm -ubsan-unique-traps %s -o - \ -// RUN: | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 -mllvm -ubsan-unique-traps %s -o - -fsanitize-trap=signed-integer-overflow | FileCheck %s --check-prefix=TRAP +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 -mllvm -ubsan-unique-traps %s -o - | FileCheck %s --check-prefix=HANDLER +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -fsanitize=signed-integer-overflow -O3 -mllvm -ubsan-unique-traps %s -o - -fsanitize-minimal-runtime | FileCheck %s --check-prefix=MINRT // // REQUIRES: x86-registered-target -// CHECK-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f( -// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]] -// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// CHECK-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]] -// CHECK: [[TRAP]]: -// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], !nosanitize [[META2]] -// CHECK-NEXT: unreachable, !nosanitize [[META2]] -// CHECK: [[CONT]]: -// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] -// CHECK-NEXT: ret i32 [[TMP2]] +// TRAP-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f( +// TRAP-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// TRAP-NEXT: [[ENTRY:.*:]] +// TRAP-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]] +// TRAP-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] +// TRAP-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]] +// TRAP: [[TRAP]]: +// TRAP-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4:[0-9]+]], !nosanitize [[META2]] +// TRAP-NEXT: unreachable, !nosanitize [[META2]] +// TRAP: [[CONT]]: +// TRAP-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// TRAP-NEXT: ret i32 [[TMP2]] +// +// HANDLER-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f( +// HANDLER-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// HANDLER-NEXT: [[ENTRY:.*:]] +// HANDLER-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]] +// HANDLER-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] +// HANDLER-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] +// HANDLER: [[HANDLER_ADD_OVERFLOW]]: +// HANDLER-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]] +// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1:[0-9]+]], i64 [[TMP2]], i64 125) #[[ATTR4:[0-9]+]], !nosanitize [[META2]] +// HANDLER-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER: [[CONT]]: +// HANDLER-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// HANDLER-NEXT: ret i32 [[TMP3]] +// +// MINRT-LABEL: define dso_local range(i32 -2147483523, -2147483648) i32 @f( +// MINRT-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] { +// MINRT-NEXT: [[ENTRY:.*:]] +// MINRT-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2:![0-9]+]] +// MINRT-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] +// MINRT-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3:![0-9]+]], !nosanitize [[META2]] +// MINRT: [[HANDLER_ADD_OVERFLOW]]: +// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4:[0-9]+]], !nosanitize [[META2]] +// MINRT-NEXT: unreachable, !nosanitize [[META2]] +// MINRT: [[CONT]]: +// MINRT-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// MINRT-NEXT: ret i32 [[TMP2]] // int f(int x) { return x + 125; } -// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g( -// CHECK-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// CHECK-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]] -// CHECK: [[TRAP]]: -// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// CHECK-NEXT: unreachable, !nosanitize [[META2]] -// CHECK: [[CONT]]: -// CHECK-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] -// CHECK-NEXT: ret i32 [[TMP2]] +// TRAP-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g( +// TRAP-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// TRAP-NEXT: [[ENTRY:.*:]] +// TRAP-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] +// TRAP-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] +// TRAP-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]] +// TRAP: [[TRAP]]: +// TRAP-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] +// TRAP-NEXT: unreachable, !nosanitize [[META2]] +// TRAP: [[CONT]]: +// TRAP-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// TRAP-NEXT: ret i32 [[TMP2]] +// +// HANDLER-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g( +// HANDLER-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// HANDLER-NEXT: [[ENTRY:.*:]] +// HANDLER-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] +// HANDLER-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] +// HANDLER-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER: [[HANDLER_ADD_OVERFLOW]]: +// HANDLER-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]] +// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META2]] +// HANDLER-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER: [[CONT]]: +// HANDLER-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// HANDLER-NEXT: ret i32 [[TMP3]] +// +// MINRT-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @g( +// MINRT-SAME: i32 noundef [[X:%.*]]) local_unnamed_addr #[[ATTR0]] { +// MINRT-NEXT: [[ENTRY:.*:]] +// MINRT-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] +// MINRT-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] +// MINRT-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT: [[HANDLER_ADD_OVERFLOW]]: +// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] +// MINRT-NEXT: unreachable, !nosanitize [[META2]] +// MINRT: [[CONT]]: +// MINRT-NEXT: [[TMP2:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// MINRT-NEXT: ret i32 [[TMP2]] // int g(int x) { return x + 127; } -// CHECK-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h( -// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] -// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// CHECK-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]] -// CHECK: [[TRAP]]: -// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// CHECK-NEXT: unreachable, !nosanitize [[META2]] -// CHECK: [[CONT]]: -// CHECK-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]] -// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] -// CHECK-NEXT: br i1 [[TMP3]], label %[[TRAP1:.*]], label %[[CONT2:.*]], !nosanitize [[META2]] -// CHECK: [[TRAP1]]: -// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// CHECK-NEXT: unreachable, !nosanitize [[META2]] -// CHECK: [[CONT2]]: -// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] -// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] -// CHECK-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP5]], i32 [[TMP4]]) -// CHECK-NEXT: ret i32 [[COND]] +// TRAP-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h( +// TRAP-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// TRAP-NEXT: [[ENTRY:.*:]] +// TRAP-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] +// TRAP-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] +// TRAP-NEXT: br i1 [[TMP1]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]] +// TRAP: [[TRAP]]: +// TRAP-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] +// TRAP-NEXT: unreachable, !nosanitize [[META2]] +// TRAP: [[CONT]]: +// TRAP-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]] +// TRAP-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] +// TRAP-NEXT: br i1 [[TMP3]], label %[[TRAP1:.*]], label %[[CONT2:.*]], !nosanitize [[META2]] +// TRAP: [[TRAP1]]: +// TRAP-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] +// TRAP-NEXT: unreachable, !nosanitize [[META2]] +// TRAP: [[CONT2]]: +// TRAP-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] +// TRAP-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// TRAP-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP5]], i32 [[TMP4]]) +// TRAP-NEXT: ret i32 [[COND]] +// +// HANDLER-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h( +// HANDLER-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// HANDLER-NEXT: [[ENTRY:.*:]] +// HANDLER-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] +// HANDLER-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] +// HANDLER-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER: [[HANDLER_ADD_OVERFLOW]]: +// HANDLER-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]] +// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB3:[0-9]+]], i64 [[TMP2]], i64 127) #[[ATTR4]], !nosanitize [[META2]] +// HANDLER-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER: [[CONT]]: +// HANDLER-NEXT: [[TMP3:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]] +// HANDLER-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP3]], 1, !nosanitize [[META2]] +// HANDLER-NEXT: br i1 [[TMP4]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER: [[HANDLER_ADD_OVERFLOW1]]: +// HANDLER-NEXT: [[TMP5:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META2]] +// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB4:[0-9]+]], i64 [[TMP5]], i64 129) #[[ATTR4]], !nosanitize [[META2]] +// HANDLER-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER: [[CONT2]]: +// HANDLER-NEXT: [[TMP6:%.*]] = extractvalue { i32, i1 } [[TMP3]], 0, !nosanitize [[META2]] +// HANDLER-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// HANDLER-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP7]], i32 [[TMP6]]) +// HANDLER-NEXT: ret i32 [[COND]] +// +// MINRT-LABEL: define dso_local range(i32 -2147483521, -2147483648) i32 @h( +// MINRT-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// MINRT-NEXT: [[ENTRY:.*:]] +// MINRT-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 127), !nosanitize [[META2]] +// MINRT-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] +// MINRT-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT: [[HANDLER_ADD_OVERFLOW]]: +// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] +// MINRT-NEXT: unreachable, !nosanitize [[META2]] +// MINRT: [[CONT]]: +// MINRT-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 129), !nosanitize [[META2]] +// MINRT-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] +// MINRT-NEXT: br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW1:.*]], label %[[CONT2:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT: [[HANDLER_ADD_OVERFLOW1]]: +// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] +// MINRT-NEXT: unreachable, !nosanitize [[META2]] +// MINRT: [[CONT2]]: +// MINRT-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] +// MINRT-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// MINRT-NEXT: [[COND:%.*]] = tail call i32 @llvm.smin.i32(i32 [[TMP5]], i32 [[TMP4]]) +// MINRT-NEXT: ret i32 [[COND]] // int h(int x, int y) { x += 127; @@ -69,37 +170,100 @@ int h(int x, int y) { return x < y ? x : y; } -// CHECK-LABEL: define dso_local noundef i32 @m( -// CHECK-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { -// CHECK-NEXT: [[ENTRY:.*:]] -// CHECK-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]] -// CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] -// CHECK-NEXT: br i1 [[TMP1]], label %[[TRAP_I:.*]], label %[[F_EXIT:.*]], !nosanitize [[META2]] -// CHECK: [[TRAP_I]]: -// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// CHECK-NEXT: unreachable, !nosanitize [[META2]] -// CHECK: [[F_EXIT]]: -// CHECK-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]] -// CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] -// CHECK-NEXT: br i1 [[TMP3]], label %[[TRAP_I2:.*]], label %[[G_EXIT:.*]], !nosanitize [[META2]] -// CHECK: [[TRAP_I2]]: -// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// CHECK-NEXT: unreachable, !nosanitize [[META2]] -// CHECK: [[G_EXIT]]: -// CHECK-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] -// CHECK-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] -// CHECK-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META2]] -// CHECK-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META2]] -// CHECK-NEXT: br i1 [[TMP7]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]] -// CHECK: [[TRAP]]: -// CHECK-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] -// CHECK-NEXT: unreachable, !nosanitize [[META2]] -// CHECK: [[CONT]]: -// CHECK-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]] -// CHECK-NEXT: ret i32 [[TMP8]] +// TRAP-LABEL: define dso_local noundef i32 @m( +// TRAP-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// TRAP-NEXT: [[ENTRY:.*:]] +// TRAP-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]] +// TRAP-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] +// TRAP-NEXT: br i1 [[TMP1]], label %[[TRAP_I:.*]], label %[[F_EXIT:.*]], !nosanitize [[META2]] +// TRAP: [[TRAP_I]]: +// TRAP-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] +// TRAP-NEXT: unreachable, !nosanitize [[META2]] +// TRAP: [[F_EXIT]]: +// TRAP-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]] +// TRAP-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] +// TRAP-NEXT: br i1 [[TMP3]], label %[[TRAP_I2:.*]], label %[[G_EXIT:.*]], !nosanitize [[META2]] +// TRAP: [[TRAP_I2]]: +// TRAP-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] +// TRAP-NEXT: unreachable, !nosanitize [[META2]] +// TRAP: [[G_EXIT]]: +// TRAP-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// TRAP-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] +// TRAP-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META2]] +// TRAP-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META2]] +// TRAP-NEXT: br i1 [[TMP7]], label %[[TRAP:.*]], label %[[CONT:.*]], !nosanitize [[META2]] +// TRAP: [[TRAP]]: +// TRAP-NEXT: tail call void @llvm.ubsantrap(i8 0) #[[ATTR4]], !nosanitize [[META2]] +// TRAP-NEXT: unreachable, !nosanitize [[META2]] +// TRAP: [[CONT]]: +// TRAP-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]] +// TRAP-NEXT: ret i32 [[TMP8]] +// +// HANDLER-LABEL: define dso_local noundef i32 @m( +// HANDLER-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// HANDLER-NEXT: [[ENTRY:.*:]] +// HANDLER-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]] +// HANDLER-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] +// HANDLER-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER: [[HANDLER_ADD_OVERFLOW_I]]: +// HANDLER-NEXT: [[TMP2:%.*]] = zext nneg i32 [[X]] to i64, !nosanitize [[META2]] +// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB1]], i64 [[TMP2]], i64 125) #[[ATTR4]], !nosanitize [[META2]] +// HANDLER-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER: [[F_EXIT]]: +// HANDLER-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// HANDLER-NEXT: [[TMP4:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]] +// HANDLER-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP4]], 1, !nosanitize [[META2]] +// HANDLER-NEXT: br i1 [[TMP5]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER: [[HANDLER_ADD_OVERFLOW_I2]]: +// HANDLER-NEXT: [[TMP6:%.*]] = zext nneg i32 [[Y]] to i64, !nosanitize [[META2]] +// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB2]], i64 [[TMP6]], i64 127) #[[ATTR4]], !nosanitize [[META2]] +// HANDLER-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER: [[G_EXIT]]: +// HANDLER-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP4]], 0, !nosanitize [[META2]] +// HANDLER-NEXT: [[TMP8:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP3]], i32 [[TMP7]]), !nosanitize [[META2]] +// HANDLER-NEXT: [[TMP9:%.*]] = extractvalue { i32, i1 } [[TMP8]], 1, !nosanitize [[META2]] +// HANDLER-NEXT: br i1 [[TMP9]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// HANDLER: [[HANDLER_ADD_OVERFLOW]]: +// HANDLER-NEXT: [[TMP10:%.*]] = zext i32 [[TMP3]] to i64, !nosanitize [[META2]] +// HANDLER-NEXT: [[TMP11:%.*]] = zext i32 [[TMP7]] to i64, !nosanitize [[META2]] +// HANDLER-NEXT: tail call void @__ubsan_handle_add_overflow_abort(ptr nonnull @[[GLOB5:[0-9]+]], i64 [[TMP10]], i64 [[TMP11]]) #[[ATTR4]], !nosanitize [[META2]] +// HANDLER-NEXT: unreachable, !nosanitize [[META2]] +// HANDLER: [[CONT]]: +// HANDLER-NEXT: [[TMP12:%.*]] = extractvalue { i32, i1 } [[TMP8]], 0, !nosanitize [[META2]] +// HANDLER-NEXT: ret i32 [[TMP12]] +// +// MINRT-LABEL: define dso_local noundef i32 @m( +// MINRT-SAME: i32 noundef [[X:%.*]], i32 noundef [[Y:%.*]]) local_unnamed_addr #[[ATTR0]] { +// MINRT-NEXT: [[ENTRY:.*:]] +// MINRT-NEXT: [[TMP0:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[X]], i32 125), !nosanitize [[META2]] +// MINRT-NEXT: [[TMP1:%.*]] = extractvalue { i32, i1 } [[TMP0]], 1, !nosanitize [[META2]] +// MINRT-NEXT: br i1 [[TMP1]], label %[[HANDLER_ADD_OVERFLOW_I:.*]], label %[[F_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT: [[HANDLER_ADD_OVERFLOW_I]]: +// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] +// MINRT-NEXT: unreachable, !nosanitize [[META2]] +// MINRT: [[F_EXIT]]: +// MINRT-NEXT: [[TMP2:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[Y]], i32 127), !nosanitize [[META2]] +// MINRT-NEXT: [[TMP3:%.*]] = extractvalue { i32, i1 } [[TMP2]], 1, !nosanitize [[META2]] +// MINRT-NEXT: br i1 [[TMP3]], label %[[HANDLER_ADD_OVERFLOW_I2:.*]], label %[[G_EXIT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT: [[HANDLER_ADD_OVERFLOW_I2]]: +// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] +// MINRT-NEXT: unreachable, !nosanitize [[META2]] +// MINRT: [[G_EXIT]]: +// MINRT-NEXT: [[TMP4:%.*]] = extractvalue { i32, i1 } [[TMP0]], 0, !nosanitize [[META2]] +// MINRT-NEXT: [[TMP5:%.*]] = extractvalue { i32, i1 } [[TMP2]], 0, !nosanitize [[META2]] +// MINRT-NEXT: [[TMP6:%.*]] = tail call { i32, i1 } @llvm.sadd.with.overflow.i32(i32 [[TMP4]], i32 [[TMP5]]), !nosanitize [[META2]] +// MINRT-NEXT: [[TMP7:%.*]] = extractvalue { i32, i1 } [[TMP6]], 1, !nosanitize [[META2]] +// MINRT-NEXT: br i1 [[TMP7]], label %[[HANDLER_ADD_OVERFLOW:.*]], label %[[CONT:.*]], !prof [[PROF3]], !nosanitize [[META2]] +// MINRT: [[HANDLER_ADD_OVERFLOW]]: +// MINRT-NEXT: tail call void @__ubsan_handle_add_overflow_minimal_abort() #[[ATTR4]], !nosanitize [[META2]] +// MINRT-NEXT: unreachable, !nosanitize [[META2]] +// MINRT: [[CONT]]: +// MINRT-NEXT: [[TMP8:%.*]] = extractvalue { i32, i1 } [[TMP6]], 0, !nosanitize [[META2]] +// MINRT-NEXT: ret i32 [[TMP8]] // int m(int x, int y) { return f(x) + g(y); } -//. -// CHECK: attributes #[[ATTR4]] = { nomerge noreturn nounwind } +// TRAP: attributes #[[ATTR4]] = { nomerge noreturn nounwind } +// HANDLER: attributes #[[ATTR4]] = { nomerge noreturn nounwind } +// MINRT: attributes #[[ATTR4]] = { nomerge noreturn nounwind } diff --git a/clang/test/CodeGen/union-tbaa1.c b/clang/test/CodeGen/union-tbaa1.c index 5263b1714c8c6..7d44c9a3fbe6b 100644 --- a/clang/test/CodeGen/union-tbaa1.c +++ b/clang/test/CodeGen/union-tbaa1.c @@ -16,21 +16,21 @@ void bar(vect32 p[][2]); // CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [2 x i32], ptr [[ARR]], i32 [[TMP0]] // CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: [[MUL:%.*]] = mul i32 [[TMP1]], [[NUM]] -// CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds [4 x [2 x %union.vect32]], ptr [[TMP]], i32 0, i32 [[TMP0]] +// CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds nuw [4 x [2 x %union.vect32]], ptr [[TMP]], i32 0, i32 [[TMP0]] // CHECK-NEXT: store i32 [[MUL]], ptr [[ARRAYIDX2]], align 8, !tbaa [[TBAA6:![0-9]+]] // CHECK-NEXT: [[ARRAYIDX5:%.*]] = getelementptr inbounds [2 x i32], ptr [[ARR]], i32 [[TMP0]], i32 1 // CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[ARRAYIDX5]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: [[MUL6:%.*]] = mul i32 [[TMP2]], [[NUM]] -// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds [4 x [2 x %union.vect32]], ptr [[TMP]], i32 0, i32 [[TMP0]], i32 1 +// CHECK-NEXT: [[ARRAYIDX8:%.*]] = getelementptr inbounds nuw [4 x [2 x %union.vect32]], ptr [[TMP]], i32 0, i32 [[TMP0]], i32 1 // CHECK-NEXT: store i32 [[MUL6]], ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA6]] // CHECK-NEXT: [[TMP3:%.*]] = lshr i32 [[MUL]], 16 // CHECK-NEXT: store i32 [[TMP3]], ptr [[VEC]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: [[TMP4:%.*]] = load i32, ptr [[INDEX]], align 4, !tbaa [[TBAA2]] -// CHECK-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds [4 x [2 x %union.vect32]], ptr [[TMP]], i32 0, i32 [[TMP4]], i32 1 -// CHECK-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds i8, ptr [[ARRAYIDX14]], i32 2 +// CHECK-NEXT: [[ARRAYIDX14:%.*]] = getelementptr inbounds nuw [4 x [2 x %union.vect32]], ptr [[TMP]], i32 0, i32 [[TMP4]], i32 1 +// CHECK-NEXT: [[ARRAYIDX15:%.*]] = getelementptr inbounds nuw i8, ptr [[ARRAYIDX14]], i32 2 // CHECK-NEXT: [[TMP5:%.*]] = load i16, ptr [[ARRAYIDX15]], align 2, !tbaa [[TBAA6]] // CHECK-NEXT: [[CONV16:%.*]] = zext i16 [[TMP5]] to i32 -// CHECK-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds i8, ptr [[VEC]], i32 4 +// CHECK-NEXT: [[ARRAYIDX17:%.*]] = getelementptr inbounds nuw i8, ptr [[VEC]], i32 4 // CHECK-NEXT: store i32 [[CONV16]], ptr [[ARRAYIDX17]], align 4, !tbaa [[TBAA2]] // CHECK-NEXT: call void @bar(ptr noundef nonnull [[TMP]]) #[[ATTR3]] // CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr nonnull [[TMP]]) #[[ATTR3]] diff --git a/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu b/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu index 838bdda825728..fab87aac18310 100644 --- a/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu +++ b/clang/test/CodeGenCUDA/amdgpu-kernel-arg-pointer-type.cu @@ -331,7 +331,7 @@ struct S { // OPT-NEXT: [[ENTRY:.*:]] // OPT-NEXT: [[COERCE_SROA_0_0_COPYLOAD:%.*]] = load ptr, ptr addrspace(4) [[TMP0]], align 8, !amdgpu.noclobber [[META4:![0-9]+]] // OPT-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[COERCE_SROA_0_0_COPYLOAD]] to ptr addrspace(1) -// OPT-NEXT: [[COERCE_SROA_2_0__SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(4) [[TMP0]], i64 8 +// OPT-NEXT: [[COERCE_SROA_2_0__SROA_IDX:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(4) [[TMP0]], i64 8 // OPT-NEXT: [[COERCE_SROA_2_0_COPYLOAD:%.*]] = load ptr, ptr addrspace(4) [[COERCE_SROA_2_0__SROA_IDX]], align 8, !amdgpu.noclobber [[META4]] // OPT-NEXT: [[TMP2:%.*]] = addrspacecast ptr [[COERCE_SROA_2_0_COPYLOAD]] to ptr addrspace(1) // OPT-NEXT: [[TMP3:%.*]] = load i32, ptr addrspace(1) [[TMP1]], align 4, !amdgpu.noclobber [[META4]] @@ -432,13 +432,13 @@ __global__ void kernel4(struct S s) { // CHECK-SPIRV-NEXT: ret void // // OPT-LABEL: define dso_local amdgpu_kernel void @_Z7kernel5P1S( -// OPT-SAME: ptr addrspace(1) nocapture noundef readonly [[S_COERCE:%.*]]) local_unnamed_addr #[[ATTR2]] { +// OPT-SAME: ptr addrspace(1) nocapture noundef readonly [[S_COERCE:%.*]]) local_unnamed_addr #[[ATTR3:[0-9]+]] { // OPT-NEXT: [[ENTRY:.*:]] // OPT-NEXT: [[TMP0:%.*]] = load ptr, ptr addrspace(1) [[S_COERCE]], align 8 // OPT-NEXT: [[TMP1:%.*]] = load i32, ptr [[TMP0]], align 4 // OPT-NEXT: [[INC:%.*]] = add nsw i32 [[TMP1]], 1 // OPT-NEXT: store i32 [[INC]], ptr [[TMP0]], align 4 -// OPT-NEXT: [[Y:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[S_COERCE]], i64 8 +// OPT-NEXT: [[Y:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[S_COERCE]], i64 8 // OPT-NEXT: [[TMP2:%.*]] = load ptr, ptr addrspace(1) [[Y]], align 8 // OPT-NEXT: [[TMP3:%.*]] = load float, ptr [[TMP2]], align 4 // OPT-NEXT: [[ADD:%.*]] = fadd contract float [[TMP3]], 1.000000e+00 @@ -539,7 +539,7 @@ struct T { // OPT-NEXT: [[ENTRY:.*:]] // OPT-NEXT: [[COERCE_SROA_0_0_COPYLOAD:%.*]] = load ptr, ptr addrspace(4) [[TMP0]], align 8, !amdgpu.noclobber [[META4]] // OPT-NEXT: [[TMP1:%.*]] = addrspacecast ptr [[COERCE_SROA_0_0_COPYLOAD]] to ptr addrspace(1) -// OPT-NEXT: [[COERCE_SROA_2_0__SROA_IDX:%.*]] = getelementptr inbounds i8, ptr addrspace(4) [[TMP0]], i64 8 +// OPT-NEXT: [[COERCE_SROA_2_0__SROA_IDX:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(4) [[TMP0]], i64 8 // OPT-NEXT: [[COERCE_SROA_2_0_COPYLOAD:%.*]] = load ptr, ptr addrspace(4) [[COERCE_SROA_2_0__SROA_IDX]], align 8, !amdgpu.noclobber [[META4]] // OPT-NEXT: [[TMP2:%.*]] = addrspacecast ptr [[COERCE_SROA_2_0_COPYLOAD]] to ptr addrspace(1) // OPT-NEXT: [[TMP3:%.*]] = load float, ptr addrspace(1) [[TMP1]], align 4, !amdgpu.noclobber [[META4]] diff --git a/clang/test/CodeGenCXX/aarch64-sve-vector-init.cpp b/clang/test/CodeGenCXX/aarch64-sve-vector-init.cpp index f9068364d0dcb..bb71eb5636652 100644 --- a/clang/test/CodeGenCXX/aarch64-sve-vector-init.cpp +++ b/clang/test/CodeGenCXX/aarch64-sve-vector-init.cpp @@ -1212,3 +1212,20 @@ void test_copy_mf8x3(__clang_svmfloat8x3_t a) { void test_copy_mf8x4(__clang_svmfloat8x4_t a) { __clang_svmfloat8x4_t b{a}; } + +/// Reduced from: https://github.com/llvm/llvm-project/issues/107609 +using vec_t = __SVInt8_t; + +// CHECK-LABEL: define dso_local void @_Z20test_copy_s8_typedefu10__SVInt8_t +// CHECK-SAME: ( [[A:%.*]]) #[[ATTR0]] { +// CHECK-NEXT: entry: +// CHECK-NEXT: [[A_ADDR:%.*]] = alloca , align 16 +// CHECK-NEXT: [[VEC:%.*]] = alloca , align 16 +// CHECK-NEXT: store [[A]], ptr [[A_ADDR]], align 16 +// CHECK-NEXT: [[TMP0:%.*]] = load , ptr [[A_ADDR]], align 16 +// CHECK-NEXT: store [[TMP0]], ptr [[VEC]], align 16 +// CHECK-NEXT: ret void +// +void test_copy_s8_typedef(__SVInt8_t a) { + vec_t vec{a}; +} diff --git a/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp b/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp index 0cdc3b32521ff..a2cc9f30f026a 100644 --- a/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp +++ b/clang/test/CodeGenCXX/attr-target-clones-aarch64.cpp @@ -57,8 +57,8 @@ void run_foo_tml() { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 9007199254806528 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 9007199254806528 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 9007199254806784 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 9007199254806784 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] // CHECK: [[RESOLVER_RETURN]]: @@ -77,8 +77,8 @@ void run_foo_tml() { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 9007199254806528 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 9007199254806528 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 9007199254806784 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 9007199254806784 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] // CHECK: [[RESOLVER_RETURN]]: @@ -173,16 +173,16 @@ void run_foo_tml() { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36591746972385280 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36591746972385280 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36596145153180416 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36596145153180416 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] // CHECK: [[RESOLVER_RETURN]]: // CHECK-NEXT: ret ptr @_ZN7MyClassIssE7foo_tmlEv._Msme-f64f64Mssbs // CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 16777216 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 16777216 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 16777472 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 16777472 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label %[[RESOLVER_RETURN1:.*]], label %[[RESOLVER_ELSE2:.*]] // CHECK: [[RESOLVER_RETURN1]]: @@ -222,16 +222,16 @@ void run_foo_tml() { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36591746972385280 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36591746972385280 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36596145153180416 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36596145153180416 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] // CHECK: [[RESOLVER_RETURN]]: // CHECK-NEXT: ret ptr @_ZN7MyClassIisE7foo_tmlEv._Msme-f64f64Mssbs // CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 16777216 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 16777216 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 16777472 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 16777472 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label %[[RESOLVER_RETURN1:.*]], label %[[RESOLVER_ELSE2:.*]] // CHECK: [[RESOLVER_RETURN1]]: diff --git a/clang/test/CodeGenCXX/attr-target-version.cpp b/clang/test/CodeGenCXX/attr-target-version.cpp index 0fd9bc33df809..b6ba07ed29504 100644 --- a/clang/test/CodeGenCXX/attr-target-version.cpp +++ b/clang/test/CodeGenCXX/attr-target-version.cpp @@ -235,8 +235,8 @@ int bar() { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36028797153181696 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36028797153181696 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 36033195199759104 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 36033195199759104 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] // CHECK: [[RESOLVER_RETURN]]: @@ -249,8 +249,8 @@ int bar() { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 134217760 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 134217760 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 134218528 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 134218528 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] // CHECK: [[RESOLVER_RETURN]]: @@ -271,8 +271,8 @@ int bar() { // CHECK-NEXT: ret ptr @_ZN7MyClass3gooEi._Mcrc // CHECK: [[RESOLVER_ELSE]]: // CHECK-NEXT: [[TMP4:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 16 -// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 16 +// CHECK-NEXT: [[TMP5:%.*]] = and i64 [[TMP4]], 784 +// CHECK-NEXT: [[TMP6:%.*]] = icmp eq i64 [[TMP5]], 784 // CHECK-NEXT: [[TMP7:%.*]] = and i1 true, [[TMP6]] // CHECK-NEXT: br i1 [[TMP7]], label %[[RESOLVER_RETURN1:.*]], label %[[RESOLVER_ELSE2:.*]] // CHECK: [[RESOLVER_RETURN1]]: @@ -285,8 +285,8 @@ int bar() { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073807616 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073807616 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] // CHECK: [[RESOLVER_RETURN]]: @@ -299,8 +299,8 @@ int bar() { // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65536 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65536 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 65792 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 65792 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] // CHECK: [[RESOLVER_RETURN]]: diff --git a/clang/test/CodeGenCXX/auto-var-init.cpp b/clang/test/CodeGenCXX/auto-var-init.cpp index 7c323c2d368c0..94386e44573b5 100644 --- a/clang/test/CodeGenCXX/auto-var-init.cpp +++ b/clang/test/CodeGenCXX/auto-var-init.cpp @@ -1296,7 +1296,7 @@ TEST_CUSTOM(semivolatile, semivolatile, { 0x44444444, 0x44444444 }); // CHECK-NOT: !annotation // CHECK-O0: call void @{{.*}}used{{.*}}%custom) // PATTERN-O1: store i32 1145324612, ptr %custom, align 4 -// PATTERN-O1-NEXT: %[[I:[^ ]*]] = getelementptr inbounds i8, ptr %custom, i64 4 +// PATTERN-O1-NEXT: %[[I:[^ ]*]] = getelementptr inbounds nuw i8, ptr %custom, i64 4 // PATTERN-O1-NEXT: store i32 1145324612, ptr %[[I]], align 4 // ZERO-O1: store i64 4919131752989213764, ptr %custom, align 8 // CHECK-NOT: !annotation @@ -1338,7 +1338,7 @@ TEST_UNINIT(base, base); // PATTERN-O0: call void @llvm.memcpy{{.*}} @__const.test_base_uninit.uninit{{.+}}), !annotation [[AUTO_INIT]] // ZERO-LABEL: @test_base_uninit() // ZERO-O0: call void @llvm.memset{{.*}}, i8 0,{{.+}}), !annotation [[AUTO_INIT]] -// ZERO-O1: store ptr getelementptr inbounds inrange(-16, 16) (i8, ptr @_ZTV4base, i64 16), {{.*}}, align 8 +// ZERO-O1: store ptr getelementptr inbounds nuw inrange(-16, 16) (i8, ptr @_ZTV4base, i64 16), {{.*}}, align 8 // ZERO-O1-NOT: !annotation TEST_BRACES(base, base); @@ -1359,7 +1359,7 @@ TEST_UNINIT(derived, derived); // ZERO-LABEL: @test_derived_uninit() // ZERO-O0: call void @llvm.memset{{.*}}, i8 0, {{.+}}), !annotation [[AUTO_INIT]] // ZERO-O1: store i64 0, {{.*}} align 8, !annotation [[AUTO_INIT]] -// ZERO-O1: store ptr getelementptr inbounds inrange(-16, 16) (i8, ptr @_ZTV7derived, i64 16), {{.*}} align 8 +// ZERO-O1: store ptr getelementptr inbounds nuw inrange(-16, 16) (i8, ptr @_ZTV7derived, i64 16), {{.*}} align 8 TEST_BRACES(derived, derived); // CHECK-LABEL: @test_derived_braces() @@ -1494,11 +1494,11 @@ TEST_CUSTOM(unmatchedreverse, unmatchedreverse, { .c = 42 }); // CHECK-NOT: !annotation // CHECK-O0: call void @{{.*}}used{{.*}}%custom) // PATTERN-O1: store i8 42, ptr {{.*}}, align 4 -// PATTERN-O1-NEXT: %[[I:[^ ]*]] = getelementptr inbounds i8, ptr %custom, i64 1 +// PATTERN-O1-NEXT: %[[I:[^ ]*]] = getelementptr inbounds nuw i8, ptr %custom, i64 1 // PATTERN-O1-NEXT: store i8 -86, ptr %[[I]], align {{.*}} -// PATTERN-O1-NEXT: %[[I:[^ ]*]] = getelementptr inbounds i8, ptr %custom, i64 2 +// PATTERN-O1-NEXT: %[[I:[^ ]*]] = getelementptr inbounds nuw i8, ptr %custom, i64 2 // PATTERN-O1-NEXT: store i8 -86, ptr %[[I]], align {{.*}} -// PATTERN-O1-NEXT: %[[I:[^ ]*]] = getelementptr inbounds i8, ptr %custom, i64 3 +// PATTERN-O1-NEXT: %[[I:[^ ]*]] = getelementptr inbounds nuw i8, ptr %custom, i64 3 // PATTERN-O1-NEXT: store i8 -86, ptr %[[I]], align {{.*}} // ZERO-O1: store i32 42, ptr {{.*}}, align 4 diff --git a/clang/test/CodeGenCXX/catch-undef-behavior.cpp b/clang/test/CodeGenCXX/catch-undef-behavior.cpp index a985183129911..419d1292551a0 100644 --- a/clang/test/CodeGenCXX/catch-undef-behavior.cpp +++ b/clang/test/CodeGenCXX/catch-undef-behavior.cpp @@ -734,6 +734,6 @@ void ThisAlign::this_align_lambda_2() { p(); } -// CHECK: attributes [[NR_NUW]] = { noreturn nounwind } +// CHECK: attributes [[NR_NUW]] = { nomerge noreturn nounwind } // CHECK-FUNCSAN: ![[FUNCSAN]] = !{i32 -1056584962, i32 -1000226989} diff --git a/clang/test/CodeGenCXX/ext-int.cpp b/clang/test/CodeGenCXX/ext-int.cpp index 97b5d6ce16b88..f470398ec2095 100644 --- a/clang/test/CodeGenCXX/ext-int.cpp +++ b/clang/test/CodeGenCXX/ext-int.cpp @@ -549,24 +549,6 @@ void Shift(_BitInt(28) Ext, _BitInt(65) LargeExt, int i) { // CHECK: ashr i65 {{.+}}, %[[PROMO]] } -void ComplexTest(_Complex _BitInt(12) first, _Complex _BitInt(33) second) { - // LIN: define{{.*}} void @_Z11ComplexTestCDB12_CDB33_ - // WIN: define dso_local void @"?ComplexTest@@YAXU?$_Complex@U?$_BitInt@$0M@@__clang@@@__clang@@U?$_Complex@U?$_BitInt@$0CB@@__clang@@@2@@Z" - first + second; - // CHECK: %[[FIRST_REALP:.+]] = getelementptr inbounds nuw { i12, i12 }, ptr %{{.+}}, i32 0, i32 0 - // CHECK: %[[FIRST_REAL:.+]] = load i12, ptr %[[FIRST_REALP]] - // CHECK: %[[FIRST_IMAGP:.+]] = getelementptr inbounds nuw { i12, i12 }, ptr %{{.+}}, i32 0, i32 1 - // CHECK: %[[FIRST_IMAG:.+]] = load i12, ptr %[[FIRST_IMAGP]] - // CHECK: %[[FIRST_REAL_CONV:.+]] = sext i12 %[[FIRST_REAL]] - // CHECK: %[[FIRST_IMAG_CONV:.+]] = sext i12 %[[FIRST_IMAG]] - // CHECK: %[[SECOND_REALP:.+]] = getelementptr inbounds nuw { i33, i33 }, ptr %{{.+}}, i32 0, i32 0 - // CHECK: %[[SECOND_REAL:.+]] = load i33, ptr %[[SECOND_REALP]] - // CHECK: %[[SECOND_IMAGP:.+]] = getelementptr inbounds nuw { i33, i33 }, ptr %{{.+}}, i32 0, i32 1 - // CHECK: %[[SECOND_IMAG:.+]] = load i33, ptr %[[SECOND_IMAGP]] - // CHECK: %[[REAL:.+]] = add i33 %[[FIRST_REAL_CONV]], %[[SECOND_REAL]] - // CHECK: %[[IMAG:.+]] = add i33 %[[FIRST_IMAG_CONV]], %[[SECOND_IMAG]] -} - typedef _BitInt(64) vint64_t16 __attribute__((vector_size(16))); void VectorTest(vint64_t16 first, vint64_t16 second) { // LIN: define{{.*}} void @_Z10VectorTestDv2_DB64_S0_(<2 x i64> %{{.+}}, <2 x i64> %{{.+}}) diff --git a/clang/test/CodeGenCXX/fmv-namespace.cpp b/clang/test/CodeGenCXX/fmv-namespace.cpp index d61f6dc9a7071..1a76ee0356524 100644 --- a/clang/test/CodeGenCXX/fmv-namespace.cpp +++ b/clang/test/CodeGenCXX/fmv-namespace.cpp @@ -76,8 +76,8 @@ __attribute((target_version("mops"))) int bar() { return 1; } // CHECK-NEXT: [[RESOLVER_ENTRY:.*:]] // CHECK-NEXT: call void @__init_cpu_features_resolver() // CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8 -// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824 -// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824 +// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073807616 +// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073807616 // CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]] // CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]] // CHECK: [[RESOLVER_RETURN]]: diff --git a/clang/test/CodeGenCXX/matrix-vector-bit-int.cpp b/clang/test/CodeGenCXX/matrix-vector-bit-int.cpp new file mode 100644 index 0000000000000..040615f417085 --- /dev/null +++ b/clang/test/CodeGenCXX/matrix-vector-bit-int.cpp @@ -0,0 +1,98 @@ +// RUN: %clang_cc1 -fenable-matrix %s -emit-llvm -triple x86_64-unknown-linux -disable-llvm-passes -o - -std=c++11 | FileCheck %s + +using i8x3 = _BitInt(8) __attribute__((ext_vector_type(3))); +using i8x3x3 = _BitInt(8) __attribute__((matrix_type(3, 3))); +using i32x3 = _BitInt(32) __attribute__((ext_vector_type(3))); +using i32x3x3 = _BitInt(32) __attribute__((matrix_type(3, 3))); +using i512x3 = _BitInt(512) __attribute__((ext_vector_type(3))); +using i512x3x3 = _BitInt(512) __attribute__((matrix_type(3, 3))); + +// CHECK-LABEL: define dso_local i32 @_Z2v1Dv3_DB8_(i32 %a.coerce) +i8x3 v1(i8x3 a) { + // CHECK-NEXT: entry: + // CHECK-NEXT: %retval = alloca <3 x i8>, align 4 + // CHECK-NEXT: %a = alloca <3 x i8>, align 4 + // CHECK-NEXT: %a.addr = alloca <3 x i8>, align 4 + // CHECK-NEXT: store i32 %a.coerce, ptr %a, align 4 + // CHECK-NEXT: %loadVec4 = load <4 x i8>, ptr %a, align 4 + // CHECK-NEXT: %a1 = shufflevector <4 x i8> %loadVec4, <4 x i8> poison, <3 x i32> + // CHECK-NEXT: %extractVec = shufflevector <3 x i8> %a1, <3 x i8> poison, <4 x i32> + // CHECK-NEXT: store <4 x i8> %extractVec, ptr %a.addr, align 4 + // CHECK-NEXT: %loadVec42 = load <4 x i8>, ptr %a.addr, align 4 + // CHECK-NEXT: %extractVec3 = shufflevector <4 x i8> %loadVec42, <4 x i8> poison, <3 x i32> + // CHECK-NEXT: %loadVec44 = load <4 x i8>, ptr %a.addr, align 4 + // CHECK-NEXT: %extractVec5 = shufflevector <4 x i8> %loadVec44, <4 x i8> poison, <3 x i32> + // CHECK-NEXT: %add = add <3 x i8> %extractVec3, %extractVec5 + // CHECK-NEXT: store <3 x i8> %add, ptr %retval, align 4 + // CHECK-NEXT: %0 = load i32, ptr %retval, align 4 + // CHECK-NEXT: ret i32 %0 + return a + a; +} + +// CHECK-LABEL: define dso_local noundef <3 x i32> @_Z2v2Dv3_DB32_(<3 x i32> noundef %a) +i32x3 v2(i32x3 a) { + // CHECK-NEXT: entry: + // CHECK-NEXT: %a.addr = alloca <3 x i32>, align 16 + // CHECK-NEXT: %extractVec = shufflevector <3 x i32> %a, <3 x i32> poison, <4 x i32> + // CHECK-NEXT: store <4 x i32> %extractVec, ptr %a.addr, align 16 + // CHECK-NEXT: %loadVec4 = load <4 x i32>, ptr %a.addr, align 16 + // CHECK-NEXT: %extractVec1 = shufflevector <4 x i32> %loadVec4, <4 x i32> poison, <3 x i32> + // CHECK-NEXT: %loadVec42 = load <4 x i32>, ptr %a.addr, align 16 + // CHECK-NEXT: %extractVec3 = shufflevector <4 x i32> %loadVec42, <4 x i32> poison, <3 x i32> + // CHECK-NEXT: %add = add <3 x i32> %extractVec1, %extractVec3 + // CHECK-NEXT: ret <3 x i32> %add + return a + a; +} + +// CHECK-LABEL: define dso_local noundef <3 x i512> @_Z2v3Dv3_DB512_(ptr noundef byval(<3 x i512>) align 256 %0) +i512x3 v3(i512x3 a) { + // CHECK-NEXT: entry: + // CHECK-NEXT: %a.addr = alloca <3 x i512>, align 256 + // CHECK-NEXT: %loadVec4 = load <4 x i512>, ptr %0, align 256 + // CHECK-NEXT: %a = shufflevector <4 x i512> %loadVec4, <4 x i512> poison, <3 x i32> + // CHECK-NEXT: %extractVec = shufflevector <3 x i512> %a, <3 x i512> poison, <4 x i32> + // CHECK-NEXT: store <4 x i512> %extractVec, ptr %a.addr, align 256 + // CHECK-NEXT: %loadVec41 = load <4 x i512>, ptr %a.addr, align 256 + // CHECK-NEXT: %extractVec2 = shufflevector <4 x i512> %loadVec41, <4 x i512> poison, <3 x i32> + // CHECK-NEXT: %loadVec43 = load <4 x i512>, ptr %a.addr, align 256 + // CHECK-NEXT: %extractVec4 = shufflevector <4 x i512> %loadVec43, <4 x i512> poison, <3 x i32> + // CHECK-NEXT: %add = add <3 x i512> %extractVec2, %extractVec4 + // CHECK-NEXT: ret <3 x i512> %add + return a + a; +} + +// CHECK-LABEL: define dso_local noundef <9 x i8> @_Z2m1u11matrix_typeILm3ELm3EDB8_E(<9 x i8> noundef %a) +i8x3x3 m1(i8x3x3 a) { + // CHECK-NEXT: entry: + // CHECK-NEXT: %a.addr = alloca [9 x i8], align 1 + // CHECK-NEXT: store <9 x i8> %a, ptr %a.addr, align 1 + // CHECK-NEXT: %0 = load <9 x i8>, ptr %a.addr, align 1 + // CHECK-NEXT: %1 = load <9 x i8>, ptr %a.addr, align 1 + // CHECK-NEXT: %2 = add <9 x i8> %0, %1 + // CHECK-NEXT: ret <9 x i8> %2 + return a + a; +} + +// CHECK-LABEL: define dso_local noundef <9 x i32> @_Z2m2u11matrix_typeILm3ELm3EDB32_E(<9 x i32> noundef %a) +i32x3x3 m2(i32x3x3 a) { + // CHECK-NEXT: entry: + // CHECK-NEXT: %a.addr = alloca [9 x i32], align 4 + // CHECK-NEXT: store <9 x i32> %a, ptr %a.addr, align 4 + // CHECK-NEXT: %0 = load <9 x i32>, ptr %a.addr, align 4 + // CHECK-NEXT: %1 = load <9 x i32>, ptr %a.addr, align 4 + // CHECK-NEXT: %2 = add <9 x i32> %0, %1 + // CHECK-NEXT: ret <9 x i32> %2 + return a + a; +} + +// CHECK-LABEL: define dso_local noundef <9 x i512> @_Z2m3u11matrix_typeILm3ELm3EDB512_E(<9 x i512> noundef %a) +i512x3x3 m3(i512x3x3 a) { + // CHECK-NEXT: entry: + // CHECK-NEXT: %a.addr = alloca [9 x i512], align 8 + // CHECK-NEXT: store <9 x i512> %a, ptr %a.addr, align 8 + // CHECK-NEXT: %0 = load <9 x i512>, ptr %a.addr, align 8 + // CHECK-NEXT: %1 = load <9 x i512>, ptr %a.addr, align 8 + // CHECK-NEXT: %2 = add <9 x i512> %0, %1 + // CHECK-NEXT: ret <9 x i512> %2 + return a + a; +} diff --git a/clang/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp b/clang/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp index 4b046acf0d878..a5d0d5ad6e91f 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp @@ -18,7 +18,7 @@ T* test1(V* x) { return &dynamic_cast(*x); } T* test2(A* x) { return &dynamic_cast(*x); } // CHECK-LABEL: define dso_local noundef ptr @"?test2@@YAPAUT@@PAUA@@@Z"(ptr noundef %x) // CHECK: [[VBTBL:%.*]] = load ptr, ptr %x, align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i8, ptr [[VBTBL]], i32 4 +// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds nuw i8, ptr [[VBTBL]], i32 4 // CHECK-NEXT: [[VBOFFS:%.*]] = load i32, ptr [[VBOFFP]], align 4 // CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, ptr %x, i32 [[VBOFFS]] // CHECK-NEXT: [[CALL:%.*]] = tail call ptr @__RTDynamicCast(ptr nonnull [[ADJ]], i32 [[VBOFFS]], ptr nonnull @"??_R0?AUA@@@8", ptr nonnull @"??_R0?AUT@@@8", i32 1) @@ -26,9 +26,9 @@ T* test2(A* x) { return &dynamic_cast(*x); } T* test3(B* x) { return &dynamic_cast(*x); } // CHECK-LABEL: define dso_local noundef ptr @"?test3@@YAPAUT@@PAUB@@@Z"(ptr noundef %x) -// CHECK: [[VBPTR:%.*]] = getelementptr inbounds i8, ptr %x, i32 4 +// CHECK: [[VBPTR:%.*]] = getelementptr inbounds nuw i8, ptr %x, i32 4 // CHECK-NEXT: [[VBTBL:%.*]] = load ptr, ptr [[VBPTR:%.*]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i8, ptr [[VBTBL]], i32 4 +// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds nuw i8, ptr [[VBTBL]], i32 4 // CHECK-NEXT: [[VBOFFS:%.*]] = load i32, ptr [[VBOFFP]], align 4 // CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4 // CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, ptr %x, i32 [[DELTA]] @@ -45,7 +45,7 @@ T* test5(A* x) { return dynamic_cast(x); } // CHECK: [[CHECK:%.*]] = icmp eq ptr %x, null // CHECK-NEXT: br i1 [[CHECK]] // CHECK: [[VBTBL:%.*]] = load ptr, ptr %x, align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i8, ptr [[VBTBL]], i32 4 +// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds nuw i8, ptr [[VBTBL]], i32 4 // CHECK-NEXT: [[VBOFFS:%.*]] = load i32, ptr [[VBOFFP]], align 4 // CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, ptr %x, i32 [[VBOFFS]] // CHECK-NEXT: [[CALL:%.*]] = tail call ptr @__RTDynamicCast(ptr nonnull [[ADJ]], i32 [[VBOFFS]], ptr {{.*}}@"??_R0?AUA@@@8", ptr {{.*}}@"??_R0?AUT@@@8", i32 0) @@ -57,9 +57,9 @@ T* test6(B* x) { return dynamic_cast(x); } // CHECK-LABEL: define dso_local noundef ptr @"?test6@@YAPAUT@@PAUB@@@Z"(ptr noundef %x) // CHECK: [[CHECK:%.*]] = icmp eq ptr %x, null // CHECK-NEXT: br i1 [[CHECK]] -// CHECK: [[VBPTR:%.*]] = getelementptr inbounds i8, ptr %x, i32 4 +// CHECK: [[VBPTR:%.*]] = getelementptr inbounds nuw i8, ptr %x, i32 4 // CHECK-NEXT: [[VBTBL:%.*]] = load ptr, ptr [[VBPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i8, ptr [[VBTBL]], i32 4 +// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds nuw i8, ptr [[VBTBL]], i32 4 // CHECK-NEXT: [[VBOFFS:%.*]] = load i32, ptr [[VBOFFP]], align 4 // CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4 // CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, ptr %x, i32 [[DELTA]] @@ -78,7 +78,7 @@ void* test8(A* x) { return dynamic_cast(x); } // CHECK: [[CHECK:%.*]] = icmp eq ptr %x, null // CHECK-NEXT: br i1 [[CHECK]] // CHECK: [[VBTBL:%.*]] = load ptr, ptr %x, align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i8, ptr [[VBTBL]], i32 4 +// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds nuw i8, ptr [[VBTBL]], i32 4 // CHECK-NEXT: [[VBOFFS:%.*]] = load i32, ptr [[VBOFFP]], align 4 // CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, ptr %x, i32 [[VBOFFS]] // CHECK-NEXT: [[RES:%.*]] = tail call ptr @__RTCastToVoid(ptr nonnull [[ADJ]]) @@ -90,9 +90,9 @@ void* test9(B* x) { return dynamic_cast(x); } // CHECK-LABEL: define dso_local noundef ptr @"?test9@@YAPAXPAUB@@@Z"(ptr noundef %x) // CHECK: [[CHECK:%.*]] = icmp eq ptr %x, null // CHECK-NEXT: br i1 [[CHECK]] -// CHECK: [[VBPTR:%.*]] = getelementptr inbounds i8, ptr %x, i32 4 +// CHECK: [[VBPTR:%.*]] = getelementptr inbounds nuw i8, ptr %x, i32 4 // CHECK-NEXT: [[VBTBL:%.*]] = load ptr, ptr [[VBPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i8, ptr [[VBTBL]], i32 4 +// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds nuw i8, ptr [[VBTBL]], i32 4 // CHECK-NEXT: [[VBOFFS:%.*]] = load i32, ptr [[VBOFFP]], align 4 // CHECK-NEXT: [[BASE:%.*]] = getelementptr i8, ptr %x, i32 [[VBOFFS]] // CHECK-NEXT: [[ADJ:%.*]] = getelementptr i8, ptr [[BASE]], i32 4 diff --git a/clang/test/CodeGenCXX/microsoft-abi-typeid.cpp b/clang/test/CodeGenCXX/microsoft-abi-typeid.cpp index 31d7d23fd6fc5..24a19cd856602 100644 --- a/clang/test/CodeGenCXX/microsoft-abi-typeid.cpp +++ b/clang/test/CodeGenCXX/microsoft-abi-typeid.cpp @@ -31,7 +31,7 @@ const std::type_info* test3_typeid() { return &typeid(*fn()); } // CHECK: call ptr @__RTtypeid(ptr null) // CHECK-NEXT: unreachable // CHECK: [[VBTBL:%.*]] = load ptr, ptr [[CALL]], align 4 -// CHECK-NEXT: [[VBSLOT:%.*]] = getelementptr inbounds i8, ptr [[VBTBL]], i32 4 +// CHECK-NEXT: [[VBSLOT:%.*]] = getelementptr inbounds nuw i8, ptr [[VBTBL]], i32 4 // CHECK-NEXT: [[VBASE_OFFS:%.*]] = load i32, ptr [[VBSLOT]], align 4 // CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, ptr [[CALL]], i32 [[VBASE_OFFS]] // CHECK-NEXT: [[RT:%.*]] = tail call ptr @__RTtypeid(ptr nonnull [[ADJ]]) diff --git a/clang/test/CodeGenHLSL/builtins/AppendStructuredBuffer-elementtype.hlsl b/clang/test/CodeGenHLSL/builtins/AppendStructuredBuffer-elementtype.hlsl index 1e8aae588fc33..85face8eaeb6c 100644 --- a/clang/test/CodeGenHLSL/builtins/AppendStructuredBuffer-elementtype.hlsl +++ b/clang/test/CodeGenHLSL/builtins/AppendStructuredBuffer-elementtype.hlsl @@ -18,7 +18,8 @@ struct MyStruct { // DXIL: %"class.hlsl::AppendStructuredBuffer.9" = type { target("dx.RawBuffer", <3 x i32>, 1, 0) // DXIL: %"class.hlsl::AppendStructuredBuffer.10" = type { target("dx.RawBuffer", <2 x half>, 1, 0) // DXIL: %"class.hlsl::AppendStructuredBuffer.11" = type { target("dx.RawBuffer", <3 x float>, 1, 0) -// DXIL: %"class.hlsl::AppendStructuredBuffer.12" = type { target("dx.RawBuffer", %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] }, 1, 0) +// DXIL: %"class.hlsl::AppendStructuredBuffer.12" = type { target("dx.RawBuffer", %struct.MyStruct, 1, 0) +// DXIL: %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] } AppendStructuredBuffer BufI16; AppendStructuredBuffer BufU16; diff --git a/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl b/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl new file mode 100644 index 0000000000000..45e135427ba9c --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/ByteAddressBuffers-constructors.hlsl @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL +// RUN-DISABLED: %clang_cc1 -triple spirv-vulkan-library -x hlsl -emit-llvm -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV + +// NOTE: SPIRV codegen for resource types is not yet implemented + +ByteAddressBuffer Buffer0: register(t0); +RWByteAddressBuffer Buffer1: register(u1, space2); +RasterizerOrderedByteAddressBuffer Buffer2: register(u3, space4); + +// CHECK: "class.hlsl::ByteAddressBuffer" = type { target("dx.RawBuffer", i8, 0, 0) } +// CHECK: "class.hlsl::RWByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 0) } +// CHECK: "class.hlsl::RasterizerOrderedByteAddressBuffer" = type { target("dx.RawBuffer", i8, 1, 1) } + +// CHECK: @Buffer0 = global %"class.hlsl::ByteAddressBuffer" zeroinitializer, align 4 +// CHECK: @Buffer1 = global %"class.hlsl::RWByteAddressBuffer" zeroinitializer, align 4 +// CHECK: @Buffer2 = global %"class.hlsl::RasterizerOrderedByteAddressBuffer" zeroinitializer, align 4 + +// CHECK: define internal void @_GLOBAL__sub_I_ByteAddressBuffers_constructors.hlsl() +// CHECK: entry: +// CHECK: call void @_init_resource_bindings() + +// CHECK: define internal void @_init_resource_bindings() { +// CHECK-NEXT: entry: +// CHECK-DXIL-NEXT: %Buffer0_h = call target("dx.RawBuffer", i8, 0, 0) @llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_0_0t(i32 0, i32 0, i32 1, i32 0, i1 false) +// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 0, 0) %Buffer0_h, ptr @Buffer0, align 4 +// CHECK-DXIL-NEXT: %Buffer1_h = call target("dx.RawBuffer", i8, 1, 0) @llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_1_0t(i32 2, i32 1, i32 1, i32 0, i1 false) +// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 1, 0) %Buffer1_h, ptr @Buffer1, align 4 +// CHECK-DXIL-NEXT: %Buffer2_h = call target("dx.RawBuffer", i8, 1, 1) @llvm.dx.handle.fromBinding.tdx.RawBuffer_i8_1_1t(i32 4, i32 3, i32 1, i32 0, i1 false) +// CHECK-DXIL-NEXT: store target("dx.RawBuffer", i8, 1, 1) %Buffer2_h, ptr @Buffer2, align 4 diff --git a/clang/test/CodeGenHLSL/builtins/ConsumeStructuredBuffer-elementtype.hlsl b/clang/test/CodeGenHLSL/builtins/ConsumeStructuredBuffer-elementtype.hlsl index f8574c6460d4e..5ed9e9ad8160f 100644 --- a/clang/test/CodeGenHLSL/builtins/ConsumeStructuredBuffer-elementtype.hlsl +++ b/clang/test/CodeGenHLSL/builtins/ConsumeStructuredBuffer-elementtype.hlsl @@ -18,7 +18,8 @@ struct MyStruct { // DXIL: %"class.hlsl::ConsumeStructuredBuffer.9" = type { target("dx.RawBuffer", <3 x i32>, 1, 0) // DXIL: %"class.hlsl::ConsumeStructuredBuffer.10" = type { target("dx.RawBuffer", <2 x half>, 1, 0) // DXIL: %"class.hlsl::ConsumeStructuredBuffer.11" = type { target("dx.RawBuffer", <3 x float>, 1, 0) -// DXIL: %"class.hlsl::ConsumeStructuredBuffer.12" = type { target("dx.RawBuffer", %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] }, 1, 0) +// DXIL: %"class.hlsl::ConsumeStructuredBuffer.12" = type { target("dx.RawBuffer", %struct.MyStruct, 1, 0) +// DXIL: %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] } ConsumeStructuredBuffer BufI16; ConsumeStructuredBuffer BufU16; diff --git a/clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl b/clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl index 8ce8417772530..4428b77dd9ec8 100644 --- a/clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl +++ b/clang/test/CodeGenHLSL/builtins/RWBuffer-subscript.hlsl @@ -6,9 +6,16 @@ RWBuffer Out; [numthreads(1,1,1)] void main(unsigned GI : SV_GroupIndex) { // CHECK: define void @main() + // CHECK: %[[INPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) // CHECK: %[[LOAD:.*]] = load i32, ptr %[[INPTR]] // CHECK: %[[OUTPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) // CHECK: store i32 %[[LOAD]], ptr %[[OUTPTR]] Out[GI] = In[GI]; + + // CHECK: %[[INPTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) + // CHECK: %[[LOAD:.*]] = load i32, ptr %[[INPTR]] + // CHECK: %[[OUTPTR:.*]] = call noundef nonnull align 4 dereferenceable(4) ptr @llvm.dx.resource.getpointer.p0.tdx.TypedBuffer_i32_1_0_1t(target("dx.TypedBuffer", i32, 1, 0, 1) %{{.*}}, i32 %{{.*}}) + // CHECK: store i32 %[[LOAD]], ptr %[[OUTPTR]] + Out[GI] = In.Load(GI); } diff --git a/clang/test/CodeGenHLSL/builtins/RasterizerOrderedStructuredBuffer-elementtype.hlsl b/clang/test/CodeGenHLSL/builtins/RasterizerOrderedStructuredBuffer-elementtype.hlsl index 7057988de24b3..68d626de689f2 100644 --- a/clang/test/CodeGenHLSL/builtins/RasterizerOrderedStructuredBuffer-elementtype.hlsl +++ b/clang/test/CodeGenHLSL/builtins/RasterizerOrderedStructuredBuffer-elementtype.hlsl @@ -18,7 +18,7 @@ struct MyStruct { // DXIL: %"class.hlsl::RasterizerOrderedStructuredBuffer.9" = type { target("dx.RawBuffer", <3 x i32>, 1, 1) } // DXIL: %"class.hlsl::RasterizerOrderedStructuredBuffer.10" = type { target("dx.RawBuffer", <2 x half>, 1, 1) } // DXIL: %"class.hlsl::RasterizerOrderedStructuredBuffer.11" = type { target("dx.RawBuffer", <3 x float>, 1, 1) } -// DXIL: %"class.hlsl::RasterizerOrderedStructuredBuffer.12" = type { target("dx.RawBuffer", %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] }, 1, 1) } +// DXIL: %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] } RasterizerOrderedStructuredBuffer BufI16; RasterizerOrderedStructuredBuffer BufU16; diff --git a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-lib.hlsl b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-lib.hlsl index b7986ae7dda1c..53abdc71bdd4b 100644 --- a/clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-lib.hlsl +++ b/clang/test/CodeGenHLSL/builtins/StructuredBuffers-methods-lib.hlsl @@ -5,21 +5,45 @@ RWStructuredBuffer RWSB1 : register(u0); RWStructuredBuffer RWSB2 : register(u1); +AppendStructuredBuffer ASB : register(u2); +ConsumeStructuredBuffer CSB : register(u3); // CHECK: %"class.hlsl::RWStructuredBuffer" = type { target("dx.RawBuffer", float, 1, 0) } -export void TestIncrementCounter() { - RWSB1.IncrementCounter(); +export int TestIncrementCounter() { + return RWSB1.IncrementCounter(); } -// CHECK: define void @_Z20TestIncrementCounterv() -// CHECK-DXIL: call i32 @llvm.dx.bufferUpdateCounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %{{[0-9]+}}, i8 1) +// CHECK: define noundef i32 @_Z20TestIncrementCounterv() +// CHECK-DXIL: %[[INDEX:.*]] = call i32 @llvm.dx.bufferUpdateCounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %{{[0-9]+}}, i8 1) +// CHECK-DXIL: ret i32 %[[INDEX]] +export int TestDecrementCounter() { + return RWSB2.DecrementCounter(); +} + +// CHECK: define noundef i32 @_Z20TestDecrementCounterv() +// CHECK-DXIL: %[[INDEX:.*]] = call i32 @llvm.dx.bufferUpdateCounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %{{[0-9]+}}, i8 -1) +// CHECK-DXIL: ret i32 %[[INDEX]] + +export void TestAppend(float value) { + ASB.Append(value); +} + +// CHECK: define void @_Z10TestAppendf(float noundef %value) +// CHECK-DXIL: %[[VALUE:.*]] = load float, ptr %value.addr, align 4 +// CHECK-DXIL: %[[INDEX:.*]] = call i32 @llvm.dx.bufferUpdateCounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %{{[0-9]+}}, i8 1) +// CHECK-DXIL: %[[RESPTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %{{[0-9]+}}, i32 %[[INDEX]]) +// CHECK-DXIL: store float %[[VALUE]], ptr %[[RESPTR]], align 4 -export void TestDecrementCounter() { - RWSB2.DecrementCounter(); +export float TestConsume() { + return CSB.Consume(); } -// CHECK: define void @_Z20TestDecrementCounterv() -// CHECK-DXIL: call i32 @llvm.dx.bufferUpdateCounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %{{[0-9]+}}, i8 -1) +// CHECK: define noundef float @_Z11TestConsumev() +// CHECK-DXIL: %[[INDEX:.*]] = call i32 @llvm.dx.bufferUpdateCounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %1, i8 -1) +// CHECK-DXIL: %[[RESPTR:.*]] = call ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0) %0, i32 %[[INDEX]]) +// CHECK-DXIL: %[[VALUE:.*]] = load float, ptr %[[RESPTR]], align 4 +// CHECK-DXIL: ret float %[[VALUE]] // CHECK: declare i32 @llvm.dx.bufferUpdateCounter.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i8) +// CHECK: declare ptr @llvm.dx.resource.getpointer.p0.tdx.RawBuffer_f32_1_0t(target("dx.RawBuffer", float, 1, 0), i32) diff --git a/clang/test/CodeGenHLSL/builtins/WaveActiveAllTrue.hlsl b/clang/test/CodeGenHLSL/builtins/WaveActiveAllTrue.hlsl new file mode 100644 index 0000000000000..df530a9cee561 --- /dev/null +++ b/clang/test/CodeGenHLSL/builtins/WaveActiveAllTrue.hlsl @@ -0,0 +1,17 @@ +// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -triple \ +// RUN: dxil-pc-shadermodel6.3-compute %s -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-DXIL +// RUN: %clang_cc1 -finclude-default-header -fnative-half-type -triple \ +// RUN: spirv-pc-vulkan-compute %s -emit-llvm -disable-llvm-passes -o - | \ +// RUN: FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV + +// Test basic lowering to runtime function call for int values. + +// CHECK-LABEL: define {{.*}}test +bool test(bool p1) { + // CHECK-SPIRV: %[[#entry_tok0:]] = call token @llvm.experimental.convergence.entry() + // CHECK-SPIRV: %[[RET:.*]] = call spir_func i1 @llvm.spv.wave.all(i1 %{{[a-zA-Z0-9]+}}) [ "convergencectrl"(token %[[#entry_tok0]]) ] + // CHECK-DXIL: %[[RET:.*]] = call i1 @llvm.dx.wave.all(i1 %{{[a-zA-Z0-9]+}}) + // CHECK: ret i1 %[[RET]] + return WaveActiveAllTrue(p1); +} diff --git a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl index 7de62a363eedb..fda034ce7f203 100644 --- a/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl +++ b/clang/test/CodeGenHLSL/builtins/hlsl_resource_t.hlsl @@ -3,7 +3,8 @@ using handle_float_t = __hlsl_resource_t [[hlsl::resource_class(UAV)]] [[hlsl::contained_type(float)]]; // CHECK: %"class.hlsl::RWBuffer" = type { target("dx.TypedBuffer", <4 x float>, 1, 0, 0) -// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] }, 0, 0) +// CHECK: %"class.hlsl::StructuredBuffer" = type { target("dx.RawBuffer", %struct.MyStruct, 0, 0) +// CHECK: %struct.MyStruct = type { <4 x float>, <2 x i32>, [8 x i8] } // CHECK: define 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) diff --git a/clang/test/CodeGenHLSL/resource-bindings.hlsl b/clang/test/CodeGenHLSL/resource-bindings.hlsl index bfec90e1871f8..d4e6308210653 100644 --- a/clang/test/CodeGenHLSL/resource-bindings.hlsl +++ b/clang/test/CodeGenHLSL/resource-bindings.hlsl @@ -15,5 +15,5 @@ struct S { int i; }; -// CHECK: %T3S0_h = call target("dx.RawBuffer", %struct.S = type { <4 x float>, i32, [12 x i8] }, 0, 0) @llvm.dx.handle.fromBinding.tdx.RawBuffer_s_struct.Ss_0_0t(i32 0, i32 3, i32 1, i32 0, i1 false) +// CHECK: %T3S0_h = call target("dx.RawBuffer", %struct.S, 0, 0) @llvm.dx.handle.fromBinding.tdx.RawBuffer_s_struct.Ss_0_0t(i32 0, i32 3, i32 1, i32 0, i1 false) StructuredBuffer T3S0 : register(t3); diff --git a/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID.hlsl b/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID.hlsl new file mode 100644 index 0000000000000..3d347b973f39c --- /dev/null +++ b/clang/test/CodeGenHLSL/semantics/SV_GroupThreadID.hlsl @@ -0,0 +1,36 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-DXIL -DTARGET=dx +// RUN: %clang_cc1 -triple spirv-linux-vulkan-library -x hlsl -emit-llvm -finclude-default-header -disable-llvm-passes -o - %s | FileCheck %s --check-prefixes=CHECK,CHECK-SPIRV -DTARGET=spv + +// Make sure SV_GroupThreadID translated into dx.thread.id.in.group for directx target and spv.thread.id.in.group for spirv target. + +// CHECK: define void @foo() +// CHECK: %[[#ID:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 0) +// CHECK-DXIL: call void @{{.*}}foo{{.*}}(i32 %[[#ID]]) +// CHECK-SPIRV: call spir_func void @{{.*}}foo{{.*}}(i32 %[[#ID]]) +[shader("compute")] +[numthreads(8,8,1)] +void foo(uint Idx : SV_GroupThreadID) {} + +// CHECK: define void @bar() +// CHECK: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 0) +// CHECK: %[[#ID_X_:]] = insertelement <2 x i32> poison, i32 %[[#ID_X]], i64 0 +// CHECK: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 1) +// CHECK: %[[#ID_XY:]] = insertelement <2 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1 +// CHECK-DXIL: call void @{{.*}}bar{{.*}}(<2 x i32> %[[#ID_XY]]) +// CHECK-SPIRV: call spir_func void @{{.*}}bar{{.*}}(<2 x i32> %[[#ID_XY]]) +[shader("compute")] +[numthreads(8,8,1)] +void bar(uint2 Idx : SV_GroupThreadID) {} + +// CHECK: define void @test() +// CHECK: %[[#ID_X:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 0) +// CHECK: %[[#ID_X_:]] = insertelement <3 x i32> poison, i32 %[[#ID_X]], i64 0 +// CHECK: %[[#ID_Y:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 1) +// CHECK: %[[#ID_XY:]] = insertelement <3 x i32> %[[#ID_X_]], i32 %[[#ID_Y]], i64 1 +// CHECK: %[[#ID_Z:]] = call i32 @llvm.[[TARGET]].thread.id.in.group(i32 2) +// CHECK: %[[#ID_XYZ:]] = insertelement <3 x i32> %[[#ID_XY]], i32 %[[#ID_Z]], i64 2 +// CHECK-DXIL: call void @{{.*}}test{{.*}}(<3 x i32> %[[#ID_XYZ]]) +// CHECK-SPIRV: call spir_func void @{{.*}}test{{.*}}(<3 x i32> %[[#ID_XYZ]]) +[shader("compute")] +[numthreads(8,8,1)] +void test(uint3 Idx : SV_GroupThreadID) {} diff --git a/clang/test/CodeGenObjC/arc-ternary-op.m b/clang/test/CodeGenObjC/arc-ternary-op.m index d633851ac7617..4a3c00c9807a9 100644 --- a/clang/test/CodeGenObjC/arc-ternary-op.m +++ b/clang/test/CodeGenObjC/arc-ternary-op.m @@ -67,7 +67,7 @@ void test1(int cond) { // CHECK: [[T0:%.*]] = load ptr, ptr [[ARG]] // CHECK-NEXT: store ptr [[T0]], ptr [[TEMP1]] // CHECK-NEXT: br label - // CHECK: [[W:%.*]] = phi ptr [ [[T0]], {{%.*}} ], [ undef, {{%.*}} ] + // CHECK: [[W:%.*]] = phi ptr [ [[T0]], {{%.*}} ], [ poison, {{%.*}} ] // CHECK-NEXT: call void @test1_sink(ptr noundef [[T1]]) // CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[ARG]], null // CHECK-NEXT: br i1 [[T0]], diff --git a/clang/test/CodeGenObjCXX/arc.mm b/clang/test/CodeGenObjCXX/arc.mm index 7a6de17e2baa0..7883378b33828 100644 --- a/clang/test/CodeGenObjCXX/arc.mm +++ b/clang/test/CodeGenObjCXX/arc.mm @@ -75,7 +75,7 @@ void test34(int cond) { // CHECK: [[T0:%.*]] = load ptr, ptr [[ARG]] // CHECK-NEXT: store ptr [[T0]], ptr [[TEMP1]] // CHECK-NEXT: br label - // CHECK: [[W0:%.*]] = phi ptr [ [[T0]], {{%.*}} ], [ undef, {{%.*}} ] + // CHECK: [[W0:%.*]] = phi ptr [ [[T0]], {{%.*}} ], [ poison, {{%.*}} ] // CHECK: call void @_Z11test34_sinkPU15__autoreleasingP11objc_object(ptr noundef [[T1]]) // CHECK-NEXT: [[T0:%.*]] = icmp eq ptr [[ARG]], null // CHECK-NEXT: br i1 [[T0]], diff --git a/clang/test/CodeGenOpenCL/amdgpu-nullptr.cl b/clang/test/CodeGenOpenCL/amdgpu-nullptr.cl index 53cca49e87ef4..a0c106bca83c9 100644 --- a/clang/test/CodeGenOpenCL/amdgpu-nullptr.cl +++ b/clang/test/CodeGenOpenCL/amdgpu-nullptr.cl @@ -513,9 +513,9 @@ typedef struct { // CHECK-LABEL: test_memset_private // CHECK: call void @llvm.memset.p5.i64(ptr addrspace(5) noundef align 8 {{.*}}, i8 0, i64 32, i1 false) -// CHECK: [[GEP:%.*]] = getelementptr inbounds i8, ptr addrspace(5) %ptr, i32 32 +// CHECK: [[GEP:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) %ptr, i32 32 // CHECK: store ptr addrspace(5) addrspacecast (ptr null to ptr addrspace(5)), ptr addrspace(5) [[GEP]] -// CHECK: [[GEP1:%.*]] = getelementptr inbounds i8, ptr addrspace(5) {{.*}}, i32 36 +// CHECK: [[GEP1:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(5) {{.*}}, i32 36 // CHECK: store i32 0, ptr addrspace(5) [[GEP1]], align 4 void test_memset_private(private StructTy3 *ptr) { StructTy3 S3 = {0, 0, 0, 0, 0}; diff --git a/clang/test/CodeGenOpenCL/builtins-amdgcn.cl b/clang/test/CodeGenOpenCL/builtins-amdgcn.cl index c22a43146a8c8..ded5f6b5ac4fd 100644 --- a/clang/test/CodeGenOpenCL/builtins-amdgcn.cl +++ b/clang/test/CodeGenOpenCL/builtins-amdgcn.cl @@ -620,11 +620,11 @@ void test_get_local_id(int d, global int *out) // CHECK-LABEL: @test_get_workgroup_size( // CHECK: {{.*}}call align 8 dereferenceable(256){{.*}} ptr addrspace(4) @llvm.amdgcn.implicitarg.ptr() -// CHECK: getelementptr inbounds i8, ptr addrspace(4) %{{.*}}, i64 12 +// CHECK: getelementptr inbounds nuw i8, ptr addrspace(4) %{{.*}}, i64 12 // CHECK: load i16, ptr addrspace(4) %{{.*}}, align 4, !range [[$WS_RANGE:![0-9]*]], !invariant.load{{.*}}, !noundef -// CHECK: getelementptr inbounds i8, ptr addrspace(4) %{{.*}}, i64 14 +// CHECK: getelementptr inbounds nuw i8, ptr addrspace(4) %{{.*}}, i64 14 // CHECK: load i16, ptr addrspace(4) %{{.*}}, align 2, !range [[$WS_RANGE:![0-9]*]], !invariant.load{{.*}}, !noundef -// CHECK: getelementptr inbounds i8, ptr addrspace(4) %{{.*}}, i64 16 +// CHECK: getelementptr inbounds nuw i8, ptr addrspace(4) %{{.*}}, i64 16 // CHECK: load i16, ptr addrspace(4) %{{.*}}, align 8, !range [[$WS_RANGE:![0-9]*]], !invariant.load{{.*}}, !noundef void test_get_workgroup_size(int d, global int *out) { @@ -638,7 +638,7 @@ void test_get_workgroup_size(int d, global int *out) // CHECK-LABEL: @test_get_grid_size( // CHECK: {{.*}}call align 4 dereferenceable(64){{.*}} ptr addrspace(4) @llvm.amdgcn.dispatch.ptr() -// CHECK: getelementptr inbounds i8, ptr addrspace(4) %{{.*}}, i64 %{{.+}} +// CHECK: getelementptr inbounds nuw i8, ptr addrspace(4) %{{.*}}, i64 %{{.+}} // CHECK: load i32, ptr addrspace(4) %{{.*}}, align 4, !range [[$GRID_RANGE:![0-9]+]], !invariant.load void test_get_grid_size(int d, global int *out) { diff --git a/clang/test/CodeGenOpenCL/opencl_types.cl b/clang/test/CodeGenOpenCL/opencl_types.cl index 7cab853c76d9a..aac3492b7a9e8 100644 --- a/clang/test/CodeGenOpenCL/opencl_types.cl +++ b/clang/test/CodeGenOpenCL/opencl_types.cl @@ -64,12 +64,90 @@ kernel void foo(image1d_t img) { kernel void foo_ro_pipe(read_only pipe int p) {} // CHECK-SPIR: @foo_ro_pipe(target("spirv.Pipe", 0) %p) -// CHECK_AMDGCN: @foo_ro_pipe(ptr addrspace(1) %p) +// CHECK-AMDGCN: @foo_ro_pipe(ptr addrspace(1) %p) kernel void foo_wo_pipe(write_only pipe int p) {} // CHECK-SPIR: @foo_wo_pipe(target("spirv.Pipe", 1) %p) -// CHECK_AMDGCN: @foo_wo_pipe(ptr addrspace(1) %p) +// CHECK-AMDGCN: @foo_wo_pipe(ptr addrspace(1) %p) void __attribute__((overloadable)) bad1(image1d_t b, image2d_t c, image2d_t d) {} // CHECK-SPIR-LABEL: @{{_Z4bad114ocl_image1d_ro14ocl_image2d_roS0_|"\\01\?bad1@@\$\$J0YAXPAUocl_image1d_ro@@PAUocl_image2d_ro@@1@Z"}} // CHECK-AMDGCN-LABEL: @{{_Z4bad114ocl_image1d_ro14ocl_image2d_roS0_|"\\01\?bad1@@\$\$J0YAXPAUocl_image1d_ro@@PAUocl_image2d_ro@@1@Z"}}(ptr addrspace(4){{.*}}ptr addrspace(4){{.*}}ptr addrspace(4){{.*}}) + + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test20ocl_image1d_array_ro(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(read_only image1d_array_t img) {} + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test20ocl_image1d_array_wo(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(write_only image1d_array_t img) {} + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test20ocl_image1d_array_rw(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(read_write image1d_array_t img) {} + + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test21ocl_image1d_buffer_ro(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(read_only image1d_buffer_t img) {} + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test21ocl_image1d_buffer_wo(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(write_only image1d_buffer_t img) {} + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test21ocl_image1d_buffer_rw(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(read_write image1d_buffer_t img) {} + + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test20ocl_image2d_array_ro(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(read_only image2d_array_t img) {} + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test20ocl_image2d_array_wo(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(write_only image2d_array_t img) {} + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test20ocl_image2d_array_rw(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(read_write image2d_array_t img) {} + + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test14ocl_image1d_ro(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(read_only image1d_t img) {} + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test14ocl_image1d_wo(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(write_only image1d_t img) {} + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test14ocl_image1d_rw(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(read_write image1d_t img) {} + + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test14ocl_image2d_ro(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(read_only image2d_t img) {} + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test14ocl_image2d_wo(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(write_only image2d_t img) {} + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test14ocl_image2d_rw(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(read_write image2d_t img) {} + + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test14ocl_image3d_ro(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(read_only image3d_t img) {} + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test14ocl_image3d_wo(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(write_only image3d_t img) {} + +// CHECK-AMDGCN: define dso_local void @_Z20img_type_mangle_test14ocl_image3d_rw(ptr addrspace(4) %img) +__attribute__((overloadable)) +void img_type_mangle_test(read_write image3d_t img) {} diff --git a/clang/test/CodeGenOpenCLCXX/array-type-infinite-loop.clcpp b/clang/test/CodeGenOpenCLCXX/array-type-infinite-loop.clcpp index 86f21ee556ce8..697e50e199a04 100644 --- a/clang/test/CodeGenOpenCLCXX/array-type-infinite-loop.clcpp +++ b/clang/test/CodeGenOpenCLCXX/array-type-infinite-loop.clcpp @@ -2,11 +2,11 @@ //RUN: %clang_cc1 %s -triple spir -emit-llvm -O1 -o - | FileCheck %s // CHECK-LABEL: define dso_local spir_kernel void @test( -// CHECK-SAME: ptr addrspace(1) nocapture noundef readonly align 8 [[IN:%.*]], ptr addrspace(1) nocapture noundef writeonly align 8 initializes((0, 8)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !kernel_arg_addr_space [[META3:![0-9]+]] !kernel_arg_access_qual [[META4:![0-9]+]] !kernel_arg_type [[META5:![0-9]+]] !kernel_arg_base_type [[META5]] !kernel_arg_type_qual [[META6:![0-9]+]] { +// CHECK-SAME: ptr addrspace(1) nocapture noundef readonly align 8 [[IN:%.*]], ptr addrspace(1) nocapture noundef writeonly align 8 initializes((0, 8)) [[OUT:%.*]]) local_unnamed_addr #[[ATTR0:[0-9]+]] !kernel_arg_addr_space [[META4:![0-9]+]] !kernel_arg_access_qual [[META5:![0-9]+]] !kernel_arg_type [[META6:![0-9]+]] !kernel_arg_base_type [[META6]] !kernel_arg_type_qual [[META7:![0-9]+]] { // CHECK-NEXT: entry: -// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr addrspace(1) [[IN]], i32 8 -// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr addrspace(1) [[ARRAYIDX1]], align 8, !tbaa [[TBAA7:![0-9]+]] -// CHECK-NEXT: store i64 [[TMP0]], ptr addrspace(1) [[OUT]], align 8, !tbaa [[TBAA7]] +// CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds nuw i8, ptr addrspace(1) [[IN]], i32 8 +// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr addrspace(1) [[ARRAYIDX1]], align 8, !tbaa [[TBAA8:![0-9]+]] +// CHECK-NEXT: store i64 [[TMP0]], ptr addrspace(1) [[OUT]], align 8, !tbaa [[TBAA8]] // CHECK-NEXT: ret void // __kernel void test(__global long *In, __global long *Out) { @@ -14,12 +14,12 @@ __kernel void test(__global long *In, __global long *Out) { *Out = m[1]; } //. -// CHECK: [[META3]] = !{i32 1, i32 1} -// CHECK: [[META4]] = !{!"none", !"none"} -// CHECK: [[META5]] = !{!"long*", !"long*"} -// CHECK: [[META6]] = !{!"", !""} -// CHECK: [[TBAA7]] = !{[[META8:![0-9]+]], [[META8]], i64 0} -// CHECK: [[META8]] = !{!"long", [[META9:![0-9]+]], i64 0} -// CHECK: [[META9]] = !{!"omnipotent char", [[META10:![0-9]+]], i64 0} -// CHECK: [[META10]] = !{!"Simple C++ TBAA"} +// CHECK: [[META4]] = !{i32 1, i32 1} +// CHECK: [[META5]] = !{!"none", !"none"} +// CHECK: [[META6]] = !{!"long*", !"long*"} +// CHECK: [[META7]] = !{!"", !""} +// CHECK: [[TBAA8]] = !{[[META9:![0-9]+]], [[META9]], i64 0} +// CHECK: [[META9]] = !{!"long", [[META10:![0-9]+]], i64 0} +// CHECK: [[META10]] = !{!"omnipotent char", [[META11:![0-9]+]], i64 0} +// CHECK: [[META11]] = !{!"Simple C++ TBAA"} //. diff --git a/clang/test/Driver/Inputs/config-l.cfg b/clang/test/Driver/Inputs/config-l.cfg new file mode 100644 index 0000000000000..e76efafd3039a --- /dev/null +++ b/clang/test/Driver/Inputs/config-l.cfg @@ -0,0 +1,3 @@ +-Wall $-lm +-Wl,--as-needed $-Wl,-Bstatic +$-lhappy $-Wl,-Bdynamic diff --git a/clang/test/Driver/aarch64-fixed-register-global.c b/clang/test/Driver/aarch64-fixed-register-global.c deleted file mode 100644 index 7b1fb118fcdf7..0000000000000 --- a/clang/test/Driver/aarch64-fixed-register-global.c +++ /dev/null @@ -1,12 +0,0 @@ -// Check that -ffixed register handled for globals. -// Regression test for #76426 -// RUN: %clang --target=aarch64-none-gnu -ffixed-x15 -### %s 2>&1 | FileCheck %s -// CHECK-NOT: fatal error: error in backend: Invalid register name "x15". -register int i1 __asm__("x15"); - -int foo() { - return i1; -} -int main() { - return foo(); -} diff --git a/clang/test/Driver/aarch64-fujitsu-monaka.c b/clang/test/Driver/aarch64-fujitsu-monaka.c new file mode 100644 index 0000000000000..df96b36bace68 --- /dev/null +++ b/clang/test/Driver/aarch64-fujitsu-monaka.c @@ -0,0 +1,13 @@ +// RUN: %clang --target=aarch64 -mcpu=fujitsu-monaka -### -c %s 2>&1 | FileCheck -check-prefix=fujitsu-monaka %s +// RUN: %clang --target=aarch64 -mlittle-endian -mcpu=fujitsu-monaka -### -c %s 2>&1 | FileCheck -check-prefix=fujitsu-monaka %s +// RUN: %clang --target=aarch64 -mtune=fujitsu-monaka -### -c %s 2>&1 | FileCheck -check-prefix=fujitsu-monaka-TUNE %s +// RUN: %clang --target=aarch64 -mlittle-endian -mtune=fujitsu-monaka -### -c %s 2>&1 | FileCheck -check-prefix=fujitsu-monaka-TUNE %s +// fujitsu-monaka: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "fujitsu-monaka" +// fujitsu-monaka-TUNE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-cpu" "generic" + +// RUN: %clang --target=arm64 -mcpu=fujitsu-monaka -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-fujitsu-monaka %s +// RUN: %clang --target=arm64 -mlittle-endian -mcpu=fujitsu-monaka -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-fujitsu-monaka %s +// RUN: %clang --target=arm64 -mtune=fujitsu-monaka -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-fujitsu-monaka-TUNE %s +// RUN: %clang --target=arm64 -mlittle-endian -mtune=fujitsu-monaka -### -c %s 2>&1 | FileCheck -check-prefix=ARM64-fujitsu-monaka-TUNE %s +// ARM64-fujitsu-monaka: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "fujitsu-monaka" +// ARM64-fujitsu-monaka-TUNE: "-cc1"{{.*}} "-triple" "arm64{{.*}}" "-target-cpu" "generic" diff --git a/clang/test/Driver/arm-cortex-cpus-2.c b/clang/test/Driver/arm-cortex-cpus-2.c index 2f17a08140436..0ee8e05f378ef 100644 --- a/clang/test/Driver/arm-cortex-cpus-2.c +++ b/clang/test/Driver/arm-cortex-cpus-2.c @@ -544,6 +544,17 @@ // CHECK-CORTEX-A78AE-MFPU: "-target-feature" "+sha2" // CHECK-CORTEX-A78AE-MFPU: "-target-feature" "+aes" +// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a510 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A510 %s +// RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a510 -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A510-MFPU %s +// CHECK-CORTEX-A510: "-cc1"{{.*}} "-triple" "armv9a-{{.*}} "-target-cpu" "cortex-a510" +// CHECK-CORTEX-A510-NOT: "-target-feature" "{{[+-]}}sm4" +// CHECK-CORTEX-A510-NOT: "-target-feature" "{{[+-]}}sha3" +// CHECK-CORTEX-A510: "-target-feature" "-aes" +// CHECK-CORTEX-A510-SAME: {{$}} +// CHECK-CORTEX-A510-MFPU: "-cc1"{{.*}} "-target-feature" "+fp-armv8" +// CHECK-CORTEX-A510-MFPU: "-target-feature" "+sha2" +// CHECK-CORTEX-A510-MFPU: "-target-feature" "+aes" + // RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a710 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A710 %s // RUN: %clang -target armv8a-arm-none-eabi -mcpu=cortex-a710 -mfpu=crypto-neon-fp-armv8 -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-CORTEX-A710-MFPU %s // CHECK-CORTEX-A710: "-cc1"{{.*}} "-triple" "armv9a-{{.*}} "-target-cpu" "cortex-a710" diff --git a/clang/test/Driver/baremetal-multilib.yaml b/clang/test/Driver/baremetal-multilib.yaml index b6bfd0ed3a94c..853a4e9e36e43 100644 --- a/clang/test/Driver/baremetal-multilib.yaml +++ b/clang/test/Driver/baremetal-multilib.yaml @@ -10,7 +10,8 @@ # CHECK-SAME: "-x" "c++" "{{.*}}baremetal-multilib.yaml" # CHECK-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" # CHECK-SAME: "-L[[SYSROOT]]/bin/../lib/clang-runtimes/arm-none-eabi/thumb/v8-m.main/fp/lib" -# CHECK-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" +# CHECK-SAME: "{{[^"]*}}libclang_rt.builtins.a" +# CHECK-SAME: "-lc" # CHECK-SAME: "-o" "{{.*}}.tmp.out" # RUN: %clang --multi-lib-config=%s -no-canonical-prefixes -x c++ %s -### -o %t.out 2>&1 \ diff --git a/clang/test/Driver/baremetal-sysroot.cpp b/clang/test/Driver/baremetal-sysroot.cpp index 18654be33b87c..5cbb7ac69a7ac 100644 --- a/clang/test/Driver/baremetal-sysroot.cpp +++ b/clang/test/Driver/baremetal-sysroot.cpp @@ -18,5 +18,6 @@ // CHECK-V6M-C-SAME: "-x" "c++" "{{.*}}baremetal-sysroot.cpp" // CHECK-V6M-C-NEXT: "{{[^"]*}}ld{{(\.(lld|bfd|gold))?}}{{(\.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-V6M-C-SAME: "-L{{.*}}/baremetal_default_sysroot{{[/\\]+}}bin{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+}}armv6m-none-eabi{{[/\\]+}}lib" -// CHECK-V6M-C-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-V6M-C-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-V6M-C-SAME: "-lc" // CHECK-V6M-C-SAME: "-o" "{{.*}}.o" diff --git a/clang/test/Driver/baremetal.cpp b/clang/test/Driver/baremetal.cpp index f09d7361e6c13..6d6255ef5970f 100644 --- a/clang/test/Driver/baremetal.cpp +++ b/clang/test/Driver/baremetal.cpp @@ -19,7 +19,9 @@ // CHECK-V6M-C-SAME: "[[SYSROOT:[^"]+]]{{[/\\]+}}lib{{[/\\]+}}crt0.o" // CHECK-V6M-C-SAME: "-T" "semihosted.lds" "-Lsome{{[/\\]+}}directory{{[/\\]+}}user{{[/\\]+}}asked{{[/\\]+}}for" // CHECK-V6M-C-SAME: "-L[[SYSROOT:[^"]+]]{{[/\\]+}}lib" -// CHECK-V6M-C-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "--target2=rel" "-o" "{{.*}}.tmp.out" +// CHECK-V6M-C-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-V6M-C-SAME: "-lc" +// CHECK-V6M-C-SAME: "--target2=rel" "-o" "{{.*}}.tmp.out" // RUN: %clang %s -### --target=armv6m-none-eabi -nostdlibinc -nobuiltininc 2>&1 \ // RUN: --sysroot=%S/Inputs/baremetal_arm | FileCheck --check-prefix=CHECK-V6M-LIBINC %s @@ -40,7 +42,9 @@ // CHECK-V6M-TREE-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" "-EL" // CHECK-V6M-TREE-SAME: "[[INSTALLED_DIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}armv6m-unknown-none-eabi{{[/\\]+}}crt0.o" // CHECK-V6M-TREE-SAME: "-L[[INSTALLED_DIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}armv6m-unknown-none-eabi" -// CHECK-V6M-TREE-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "--target2=rel" "-o" "{{.*}}.tmp.out" +// CHECK-V6M-TREE-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-V6M-TREE-SAME: "-lc" +// CHECK-V6M-TREE-SAME: "--target2=rel" "-o" "{{.*}}.tmp.out" // RUN: %clang %s -### --target=armv7m-vendor-none-eabi -rtlib=compiler-rt 2>&1 \ // RUN: --sysroot=%S/Inputs/baremetal_arm \ @@ -53,7 +57,8 @@ // CHECK-ARMV7M-PER_TARGET: "[[SYSROOT:[^"]+]]{{[/\\]+}}lib{{[/\\]+}}crt0.o" // CHECK-ARMV7M-PER-TARGET: "-L[[SYSROOT:[^"]+]]{{[/\\]+}}lib" // CHECK-ARMV7M-PER-TARGET: "-L[[RESOURCE_DIR:[^"]+]]{{[/\\]+}}lib{{[/\\]+}}armv7m-vendor-none-eabi -// CHECK-ARMV7M-PER-TARGET: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-ARMV7M-PER-TARGET: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-ARMV7M-PER-TARGET: "-lc" // RUN: %clangxx %s -### --target=armv6m-none-eabi 2>&1 \ // RUN: --sysroot=%S/Inputs/baremetal_arm | FileCheck --check-prefix=CHECK-V6M-DEFAULTCXX %s @@ -61,8 +66,11 @@ // CHECK-V6M-DEFAULTCXX: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" "-EL" // CHECK-V6M-DEFAULTCXX-SAME: "[[SYSROOT:[^"]+]]{{[/\\]+}}lib{{[/\\]+}}crt0.o" // CHECK-V6M-DEFAULTCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}baremetal_arm{{[/\\]+}}lib" -// CHECK-V6M-DEFAULTCXX-SAME: "-lc++" "-lc++abi" "-lunwind" -// CHECK-V6M-DEFAULTCXX-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "--target2=rel" "-o" "a.out" +// CHECK-V6M-DEFAULTCXX-SAME: "-lc++" +// CHECK-V6M-DEFAULTCXX-SAME: "-lm" +// CHECK-V6M-DEFAULTCXX-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-V6M-DEFAULTCXX-SAME: "-lc" +// CHECK-V6M-DEFAULTCXX-SAME: "--target2=rel" "-o" "a.out" // RUN: %clangxx %s -### --target=armv6m-none-eabi -stdlib=libc++ 2>&1 \ // RUN: --sysroot=%S/Inputs/baremetal_arm | FileCheck --check-prefix=CHECK-V6M-LIBCXX %s @@ -71,8 +79,11 @@ // CHECK-V6M-LIBCXX-SAME: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" // CHECK-V6M-LIBCXX: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" "-EL" // CHECK-V6M-LIBCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}baremetal_arm{{[/\\]+}}lib" -// CHECK-V6M-LIBCXX-SAME: "-lc++" "-lc++abi" "-lunwind" -// CHECK-V6M-LIBCXX-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "--target2=rel" "-o" "a.out" +// CHECK-V6M-LIBCXX-SAME: "-lc++" +// CHECK-V6M-LIBCXX-SAME: "-lm" +// CHECK-V6M-LIBCXX-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-V6M-LIBCXX-SAME: "-lc" +// CHECK-V6M-LIBCXX-SAME: "--target2=rel" "-o" "a.out" // RUN: %clangxx %s -### --target=armv6m-none-eabi 2>&1 \ // RUN: --sysroot=%S/Inputs/baremetal_arm \ @@ -83,8 +94,10 @@ // CHECK-V6M-LIBSTDCXX-SAME: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}6.0.0" // CHECK-V6M-LIBSTDCXX: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" "-EL" // CHECK-V6M-LIBSTDCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}baremetal_arm{{[/\\]+}}lib" -// CHECK-V6M-LIBSTDCXX-SAME: "-lstdc++" "-lsupc++" "-lunwind" -// CHECK-V6M-LIBSTDCXX-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "--target2=rel" "-o" "a.out" +// CHECK-V6M-LIBSTDCXX-SAME: "-lstdc++" "-lm" +// CHECK-V6M-LIBSTDCXX-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-V6M-LIBSTDCXX-SAME: "-lc" +// CHECK-V6M-LIBSTDCXX-SAME: "--target2=rel" "-o" "a.out" // RUN: %clangxx %s -### --target=armv6m-none-eabi 2>&1 \ // RUN: --sysroot=%S/Inputs/baremetal_arm \ @@ -106,8 +119,9 @@ // CHECK-V6M-LIBCXX-USR-SAME: "-internal-isystem" "{{[^"]+}}baremetal_cxx_sysroot{{[/\\]+}}usr{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" // CHECK-V6M-LIBCXX-USR: "{{[^"]*}}-Bstatic" // CHECK-V6M-LIBCXX-USR-SAME: "-L{{[^"]*}}{{[/\\]+}}baremetal_cxx_sysroot{{[/\\]+}}lib" -// CHECK-V6M-LIBCXX-USR-SAME: "-lc++" "-lc++abi" "-lunwind" -// CHECK-V6M-LIBCXX-USR-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-V6M-LIBCXX-USR-SAME: "-lc++" "-lm" +// CHECK-V6M-LIBCXX-USR-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-V6M-LIBCXX-USR-SAME: "-lc" // RUN: %clangxx --target=arm-none-eabi -v 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-THREAD-MODEL @@ -125,7 +139,7 @@ // RUN: | FileCheck %s --check-prefix=CHECK-NOSTARTFILES // CHECK-NOSTARTFILES-NOT: "crt0.o" -// RUN: %clang -### --target=arm-none-eabi -rtlib=libgcc -v %s 2>&1 \ +// RUN: %clang -### --target=arm-none-eabi -rtlib=libgcc --unwindlib=libgcc -v %s 2>&1 \ // RUN: | FileCheck %s --check-prefix=CHECK-RTLIB-GCC // CHECK-RTLIB-GCC: -lgcc @@ -194,7 +208,9 @@ // CHECK-RV64-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-RV64-SAME: "-Lsome{{[/\\]+}}directory{{[/\\]+}}user{{[/\\]+}}asked{{[/\\]+}}for" // CHECK-RV64-SAME: "-L[[SYSROOT:[^"]+]]{{[/\\]+}}lib" -// CHECK-RV64-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "-X" "-o" "{{.*}}.tmp.out" +// CHECK-RV64-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-RV64-SAME: "-lc" +// CHECK-RV64-SAME: "-X" "-o" "{{.*}}.tmp.out" // RUN: %clangxx %s -### --target=riscv64-unknown-elf 2>&1 \ // RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \ @@ -202,8 +218,10 @@ // CHECK-RV64-DEFAULTCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-RV64-DEFAULTCXX: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-RV64-DEFAULTCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv64_tree{{[/\\]+}}riscv64-unknown-elf{{[/\\]+}}lib" -// CHECK-RV64-DEFAULTCXX-SAME: "-lc++" "-lc++abi" "-lunwind" -// CHECK-RV64-DEFAULTCXX-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "-X" "-o" "a.out" +// CHECK-RV64-DEFAULTCXX-SAME: "-lc++" "-lm" +// CHECK-RV64-DEFAULTCXX-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-RV64-DEFAULTCXX-SAME: "-lc" +// CHECK-RV64-DEFAULTCXX-SAME: "-X" "-o" "a.out" // RUN: %clangxx %s -### --target=riscv64-unknown-elf 2>&1 \ // RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \ @@ -214,8 +232,10 @@ // CHECK-RV64-LIBCXX-SAME: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" // CHECK-RV64-LIBCXX: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-RV64-LIBCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv64_tree{{[/\\]+}}riscv64-unknown-elf{{[/\\]+}}lib" -// CHECK-RV64-LIBCXX-SAME: "-lc++" "-lc++abi" "-lunwind" -// CHECK-RV64-LIBCXX-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "-X" "-o" "a.out" +// CHECK-RV64-LIBCXX-SAME: "-lc++" "-lm" +// CHECK-RV64-LIBCXX-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-RV64-LIBCXX-SAME: "-lc" +// CHECK-RV64-LIBCXX-SAME: "-X" "-o" "a.out" // RUN: %clangxx %s -### 2>&1 --target=riscv64-unknown-elf \ // RUN: --sysroot=%S/Inputs/basic_riscv64_tree/riscv64-unknown-elf \ @@ -226,8 +246,10 @@ // CHECK-RV64-LIBSTDCXX-SAME: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}8.0.1" // CHECK-RV64-LIBSTDCXX: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-RV64-LIBSTDCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv64_tree{{[/\\]+}}riscv64-unknown-elf{{[/\\]+}}lib" -// CHECK-RV64-LIBSTDCXX-SAME: "-lstdc++" "-lsupc++" "-lunwind" -// CHECK-RV64-LIBSTDCXX-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "-X" "-o" "a.out" +// CHECK-RV64-LIBSTDCXX-SAME: "-lstdc++" "-lm" +// CHECK-RV64-LIBSTDCXX-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-RV64-LIBSTDCXX-SAME: "-lc" +// CHECK-RV64-LIBSTDCXX-SAME: "-X" "-o" "a.out" // RUN: %clang %s -### 2>&1 --target=riscv32-unknown-elf \ // RUN: -L some/directory/user/asked/for \ @@ -242,7 +264,9 @@ // CHECK-RV32-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-RV32-SAME: "-Lsome{{[/\\]+}}directory{{[/\\]+}}user{{[/\\]+}}asked{{[/\\]+}}for" // CHECK-RV32-SAME: "-L[[SYSROOT:[^"]+]]{{[/\\]+}}lib" -// CHECK-RV32-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "-X" "-o" "a.out" +// CHECK-RV32-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-RV32-SAME: "-lc" +// CHECK-RV32-SAME: "-X" "-o" "a.out" // RUN: %clangxx %s -### 2>&1 --target=riscv32-unknown-elf \ // RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ @@ -250,8 +274,10 @@ // CHECK-RV32-DEFAULTCXX: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" // CHECK-RV32-DEFAULTCXX: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-RV32-DEFAULTCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv32_tree{{[/\\]+}}riscv32-unknown-elf{{[/\\]+}}lib" -// CHECK-RV32-DEFAULTCXX-SAME: "-lc++" "-lc++abi" "-lunwind" -// CHECK-RV32-DEFAULTCXX-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "-X" "-o" "a.out" +// CHECK-RV32-DEFAULTCXX-SAME: "-lc++" "-lm" +// CHECK-RV32-DEFAULTCXX-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-RV32-DEFAULTCXX-SAME: "-lc" +// CHECK-RV32-DEFAULTCXX-SAME: "-X" "-o" "a.out" // RUN: %clangxx %s -### 2>&1 --target=riscv32-unknown-elf \ // RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ @@ -262,8 +288,9 @@ // CHECK-RV32-LIBCXX-SAME: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}v1" // CHECK-RV32-LIBCXX: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-RV32-LIBCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv32_tree{{[/\\]+}}riscv32-unknown-elf{{[/\\]+}}lib" -// CHECK-RV32-LIBCXX-SAME: "-lc++" "-lc++abi" "-lunwind" -// CHECK-RV32-LIBCXX-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "-X" "-o" "a.out" +// CHECK-RV32-LIBCXX-SAME: "-lc++" "-lm" +// CHECK-RV32-LIBCXX-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-RV32-LIBCXX-SAME: "-X" "-o" "a.out" // RUN: %clangxx %s -### 2>&1 --target=riscv32-unknown-elf \ // RUN: --sysroot=%S/Inputs/basic_riscv32_tree/riscv32-unknown-elf \ @@ -274,8 +301,9 @@ // CHECK-RV32-LIBSTDCXX-SAME: "-internal-isystem" "{{[^"]+}}{{[/\\]+}}include{{[/\\]+}}c++{{[/\\]+}}8.0.1" // CHECK-RV32-LIBSTDCXX: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-RV32-LIBSTDCXX-SAME: "-L{{[^"]*}}{{[/\\]+}}Inputs{{[/\\]+}}basic_riscv32_tree{{[/\\]+}}riscv32-unknown-elf{{[/\\]+}}lib" -// CHECK-RV32-LIBSTDCXX-SAME: "-lstdc++" "-lsupc++" "-lunwind" -// CHECK-RV32-LIBSTDCXX-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "-X" "-o" "a.out" +// CHECK-RV32-LIBSTDCXX-SAME: "-lstdc++" "-lm" +// CHECK-RV32-LIBSTDCXX-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-RV32-LIBSTDCXX-SAME: "-lc" "-X" "-o" "a.out" // RUN: %clang %s -### 2>&1 --target=riscv64-unknown-elf \ // RUN: -nostdlibinc -nobuiltininc \ @@ -397,7 +425,9 @@ // CHECK-PPCEABI-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include" // CHECK-PPCEABI-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-PPCEABI-SAME: "-L[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}lib" -// CHECK-PPCEABI-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "-o" "a.out" +// CHECK-PPCEABI-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-PPCEABI-SAME: "-lc" +// CHECK-PPCEABI-SAME: "-o" "a.out" // RUN: %clang -no-canonical-prefixes %s -### --target=powerpc64-unknown-eabi 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-PPC64EABI %s @@ -409,7 +439,9 @@ // CHECK-PPC64EABI-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include" // CHECK-PPC64EABI-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-PPC64EABI-SAME: "-L[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}lib" -// CHECK-PPC64EABI-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "-o" "a.out" +// CHECK-PPC64EABI-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-PPC64EABI-SAME: "-lc" +// CHECK-PPC64EABI-SAME: "-o" "a.out" // RUN: %clang -no-canonical-prefixes %s -### --target=powerpcle-unknown-eabi 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-PPCLEEABI %s @@ -421,7 +453,9 @@ // CHECK-PPCLEEABI-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include" // CHECK-PPCLEEABI-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-PPCLEEABI-SAME: "-L[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}lib" -// CHECK-PPCLEEABI-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "-o" "a.out" +// CHECK-PPCLEEABI-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-PPCLEEABI-SAME: "-lc" +// CHECK-PPCLEEABI-SAME: "-o" "a.out" // RUN: %clang -no-canonical-prefixes %s -### --target=powerpc64le-unknown-eabi 2>&1 \ // RUN: | FileCheck --check-prefix=CHECK-PPC64LEEABI %s @@ -433,7 +467,9 @@ // CHECK-PPC64LEEABI-SAME: "-internal-isystem" "[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}include" // CHECK-PPC64LEEABI-NEXT: ld{{(.exe)?}}" "{{.*}}.o" "-Bstatic" // CHECK-PPC64LEEABI-SAME: "-L[[INSTALLEDDIR]]{{[/\\]+}}..{{[/\\]+}}lib{{[/\\]+}}clang-runtimes{{[/\\]+[^"]*}}lib" -// CHECK-PPC64LEEABI-SAME: "-lc" "-lm" "{{[^"]*}}libclang_rt.builtins.a" "-o" "a.out" +// CHECK-PPC64LEEABI-SAME: "{{[^"]*}}libclang_rt.builtins.a" +// CHECK-PPC64LEEABI-SAME: "-lc" +// CHECK-PPC64LEEABI-SAME: "-o" "a.out" // Check that compiler-rt library without the arch filename suffix will // be used if present. diff --git a/clang/test/Driver/config-file.c b/clang/test/Driver/config-file.c index 9df830ca4c753..e84d6dfca373a 100644 --- a/clang/test/Driver/config-file.c +++ b/clang/test/Driver/config-file.c @@ -82,3 +82,29 @@ // CHECK-TWO-CONFIGS: -isysroot // CHECK-TWO-CONFIGS-SAME: /opt/data // CHECK-TWO-CONFIGS-SAME: -Wall + +//--- The linker input flags should be moved to the end of input list and appear only when linking. +// RUN: %clang --target=aarch64-unknown-linux-gnu --config %S/Inputs/config-l.cfg %s -lmylib -Wl,foo.a -### 2>&1 | FileCheck %s -check-prefix CHECK-LINKING +// RUN: %clang --target=aarch64-unknown-linux-gnu --config %S/Inputs/config-l.cfg -fopenmp=libomp %s -lmylib -Wl,foo.a -### 2>&1 | FileCheck %s -check-prefix CHECK-LINKING-LIBOMP-GOES-AFTER +// RUN: %clang --target=aarch64-unknown-linux-gnu --config %S/Inputs/config-l.cfg -S %s -### 2>&1 | FileCheck %s -check-prefix CHECK-NOLINKING +// RUN: %clang --target=aarch64-unknown-linux-gnu --config %S/Inputs/config-l.cfg -fopenmp=libomp -S %s -### 2>&1 | FileCheck %s -check-prefix CHECK-NOLINKING-OPENMP +// RUN: %clang --target=x86_64-pc-windows-msvc --config %S/Inputs/config-l.cfg %s -lmylib -Wl,foo.lib -### 2>&1 | FileCheck %s -check-prefix CHECK-LINKING-MSVC +// RUN: %clang --target=x86_64-pc-windows-msvc --config %S/Inputs/config-l.cfg -S %s -### 2>&1 | FileCheck %s -check-prefix CHECK-NOLINKING-MSVC +// CHECK-LINKING: Configuration file: {{.*}}Inputs{{.}}config-l.cfg +// CHECK-LINKING: "-Wall" +// CHECK-LINKING: "--as-needed" "{{.*}}-{{.*}}.o" "-lmylib" "foo.a" "-lm" "-Bstatic" "-lhappy" "-Bdynamic" +// CHECK-LINKING-LIBOMP-GOES-AFTER: Configuration file: {{.*}}Inputs{{.}}config-l.cfg +// CHECK-LINKING-LIBOMP-GOES-AFTER: "-Wall" {{.*}}"-fopenmp" +// CHECK-LINKING-LIBOMP-GOES-AFTER: "--as-needed" "{{.*}}-{{.*}}.o" "-lmylib" "foo.a" "-lm" "-Bstatic" "-lhappy" "-Bdynamic" {{.*}}"-lomp" +// CHECK-NOLINKING: Configuration file: {{.*}}Inputs{{.}}config-l.cfg +// CHECK-NOLINKING: "-Wall" +// CHECK-NOLINKING-NO: "-lm" "-Bstatic" "-lhappy" "-Bdynamic" +// CHECK-NOLINKING-OPENMP: Configuration file: {{.*}}Inputs{{.}}config-l.cfg +// CHECK-NOLINKING-OPENMP: "-Wall" {{.*}}"-fopenmp" +// CHECK-NOLINKING-OPENMP-NO: "-lm" "-Bstatic" "-lhappy" "-Bdynamic" {{.*}}"-lomp" +// CHECK-LINKING-MSVC: Configuration file: {{.*}}Inputs{{.}}config-l.cfg +// CHECK-LINKING-MSVC: "-Wall" +// CHECK-LINKING-MSVC: "--as-needed" "{{.*}}-{{.*}}.o" "mylib.lib" "foo.lib" "m.lib" "-Bstatic" "happy.lib" "-Bdynamic" +// CHECK-NOLINKING-MSVC: Configuration file: {{.*}}Inputs{{.}}config-l.cfg +// CHECK-NOLINKING-MSVC: "-Wall" +// CHECK-NOLINKING-MSVC-NO: "m.lib" "-Bstatic" "happy.lib" "-Bdynamic" diff --git a/clang/test/Driver/config-file3.c b/clang/test/Driver/config-file3.c index a0b8062c60ce5..395c31ce04b6b 100644 --- a/clang/test/Driver/config-file3.c +++ b/clang/test/Driver/config-file3.c @@ -226,3 +226,26 @@ // // RUN: HOME=%S/Inputs/config %clang -### --config-user-dir=~ -v 2>&1 | FileCheck %s --check-prefix=CHECK-TILDE // CHECK-TILDE: User configuration file directory: {{.*}}/Inputs/config + +//--- Fallback to stripping OS versions +// +// RUN: touch %t/testdmode/x86_64-apple-darwin23.6.0-clang.cfg +// RUN: touch %t/testdmode/x86_64-apple-darwin23-clang.cfg +// RUN: touch %t/testdmode/x86_64-apple-darwin-clang.cfg +// RUN: %clang -target x86_64-apple-darwin23.6.0 --config-system-dir=%t/testdmode --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix DARWIN --implicit-check-not 'Configuration file:' +// +// DARWIN: Configuration file: {{.*}}/testdmode/x86_64-apple-darwin23.6.0-clang.cfg + +//--- DARWIN + no full version +// +// RUN: rm %t/testdmode/x86_64-apple-darwin23.6.0-clang.cfg +// RUN: %clang -target x86_64-apple-darwin23.6.0 --config-system-dir=%t/testdmode --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix DARWIN-MAJOR --implicit-check-not 'Configuration file:' +// +// DARWIN-MAJOR: Configuration file: {{.*}}/testdmode/x86_64-apple-darwin23-clang.cfg + +//--- DARWIN + no version +// +// RUN: rm %t/testdmode/x86_64-apple-darwin23-clang.cfg +// RUN: %clang -target x86_64-apple-darwin23.6.0 --config-system-dir=%t/testdmode --config-user-dir= -no-canonical-prefixes --version 2>&1 | FileCheck %s -check-prefix DARWIN-VERSIONLESS --implicit-check-not 'Configuration file:' +// +// DARWIN-VERSIONLESS: Configuration file: {{.*}}/testdmode/x86_64-apple-darwin-clang.cfg diff --git a/clang/test/Driver/frame-pointer-elim.c b/clang/test/Driver/frame-pointer-elim.c index cdedcc7ae4c89..f64ff6efc7261 100644 --- a/clang/test/Driver/frame-pointer-elim.c +++ b/clang/test/Driver/frame-pointer-elim.c @@ -162,5 +162,58 @@ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s // RUN: not %clang -### --target=riscv64-linux-android -mbig-endian -O1 -S %s 2>&1 | \ // RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s + +// On ARM backend bare metal targets, frame pointer is omitted +// RUN: %clang -### --target=arm-arm-none-eabi -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: %clang -### --target=arm-arm-none-eabihf -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: %clang -### --target=arm-arm-none-eabi -S -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=arm-arm-none-eabihf -S -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=arm-arm-none-eabi -S -O1 %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: %clang -### --target=arm-arm-none-eabihf -S -O1 %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: %clang -### --target=arm-arm-none-eabi -S -O1 -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=arm-arm-none-eabihf -S -O1 -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=armeb-arm-none-eabi -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: %clang -### --target=thumb-arm-none-eabi -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NONE %s +// RUN: %clang -### --target=thumbeb-arm-none-eabi -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NONE %s + +// Check that for Apple bare metal targets, we're keeping frame pointers by default +// RUN: %clang -### --target=thumbv6m-apple-none-macho -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=thumbv6m-apple-none-macho -S -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=arm-apple-none-macho -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=arm-apple-none-macho -S -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=thumbv6m-apple-none-macho -S -O1 %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=thumbv6m-apple-none-macho -S -O1 -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=arm-apple-none-macho -S -O1 %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s +// RUN: %clang -### --target=arm-apple-none-macho -S -O1 -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-ALL %s + +// AArch64 bare metal targets behave like hosted targets +// RUN: %clang -### --target=aarch64-none-elf -S %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s +// RUN: %clang -### --target=aarch64-none-elf -S -O1 %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s +// RUN: %clang -### --target=aarch64-none-elf -S -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s +// RUN: %clang -### --target=aarch64-none-elf -S -O1 -fno-omit-frame-pointer %s 2>&1 | \ +// RUN: FileCheck --check-prefix=KEEP-NON-LEAF %s + void f0() {} void f1() { f0(); } diff --git a/clang/test/Driver/freebsd.c b/clang/test/Driver/freebsd.c index 10fe155fee874..a0787bab4feb8 100644 --- a/clang/test/Driver/freebsd.c +++ b/clang/test/Driver/freebsd.c @@ -77,6 +77,21 @@ // RUN: | FileCheck --check-prefix=CHECK-RV64I-LD %s // CHECK-RV64I-LD: ld{{.*}}" {{.*}} "-m" "elf64lriscv" // +// Check that LoongArch passes the correct linker emulation. +// +// RUN: %clang --target=loongarch32-freebsd -### %s %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-LA32-LD %s +// CHECK-LA32-LD: ld{{.*}}" {{.*}} "-m" "elf32loongarch" +// RUN: %clang --target=loongarch64-freebsd -### %s %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-LA64-LD %s +// CHECK-LA64-LD: ld{{.*}}" {{.*}} "-m" "elf64loongarch" +// +// Check options passed to the linker on LoongArch +// +// RUN: %clang --target=loongarch64-freebsd -mno-relax -### %s %s 2>&1 \ +// RUN: | FileCheck --check-prefix=CHECK-LA64-LD-OPTS %s +// CHECK-LA64-LD-OPTS: ld{{.*}}" {{.*}} "-X" "--no-relax" +// // Check that the new linker flags are passed to FreeBSD // RUN: %clang --target=x86_64-pc-freebsd10.0 -m32 %s \ // RUN: --sysroot=%S/Inputs/multiarch_freebsd64_tree -### 2>&1 \ diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c index 15f190165a7d7..bb692b2aeea1d 100644 --- a/clang/test/Driver/fsanitize.c +++ b/clang/test/Driver/fsanitize.c @@ -989,19 +989,25 @@ // RUN: not %clang --target=x86_64-linux-gnu -fsanitize=undefined,function -mcmodel=large %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION-CODE-MODEL // CHECK-UBSAN-FUNCTION-CODE-MODEL: error: invalid argument '-fsanitize=function' only allowed with '-mcmodel=small' -// RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION -// RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=undefined -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION -// RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI -// RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=function -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI --check-prefix=CHECK-UBSAN-FUNCTION +// RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION-TARGET +// RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=undefined -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION-TARGET +// RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI-TARGET +// RUN: not %clang --target=x86_64-sie-ps5 -fsanitize=function -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI-TARGET --check-prefix=CHECK-UBSAN-FUNCTION-TARGET // RUN: %clang --target=x86_64-sie-ps5 -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-UNDEFINED // CHECK-UBSAN-UNDEFINED: "-fsanitize={{((alignment|array-bounds|bool|builtin|enum|float-cast-overflow|integer-divide-by-zero|nonnull-attribute|null|pointer-overflow|return|returns-nonnull-attribute|shift-base|shift-exponent|signed-integer-overflow|unreachable|vla-bound),?){17}"}} -// RUN: not %clang --target=armv6t2-eabi -mexecute-only -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION -// RUN: not %clang --target=armv6t2-eabi -mexecute-only -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI +// RUN: not %clang --target=armv6t2-eabi -mexecute-only -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION-MEXECUTE-ONLY +// RUN: not %clang --target=armv6t2-eabi -mpure-code -fsanitize=function %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-FUNCTION-MPURE-CODE +// RUN: not %clang --target=armv6t2-eabi -mexecute-only -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI-MEXECUTE-ONLY +// RUN: not %clang --target=armv6t2-eabi -mpure-code -fsanitize=kcfi %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-KCFI-MPURE-CODE // RUN: %clang --target=armv6t2-eabi -mexecute-only -fsanitize=undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-UBSAN-UNDEFINED-VPTR -// CHECK-UBSAN-KCFI-DAG: error: invalid argument '-fsanitize=kcfi' not allowed with {{('x86_64-sie-ps5'|'armv6t2-unknown-unknown-eabi')}} -// CHECK-UBSAN-FUNCTION-DAG: error: invalid argument '-fsanitize=function' not allowed with {{('x86_64-sie-ps5'|'armv6t2-unknown-unknown-eabi')}} +// CHECK-UBSAN-KCFI-TARGET-DAG: error: unsupported option '-fsanitize=kcfi' for target 'x86_64-sie-ps5' +// CHECK-UBSAN-KCFI-MEXECUTE-ONLY-DAG: error: invalid argument '-fsanitize=kcfi' not allowed with '-mexecute-only' +// CHECK-UBSAN-KCFI-MPURE-CODE-DAG: error: invalid argument '-fsanitize=kcfi' not allowed with '-mpure-code' +// CHECK-UBSAN-FUNCTION-TARGET-DAG: error: unsupported option '-fsanitize=function' for target 'x86_64-sie-ps5' +// CHECK-UBSAN-FUNCTION-MEXECUTE-ONLY-DAG: error: invalid argument '-fsanitize=function' not allowed with '-mexecute-only' +// CHECK-UBSAN-FUNCTION-MPURE-CODE-DAG: error: invalid argument '-fsanitize=function' not allowed with '-mpure-code' // CHECK-UBSAN-UNDEFINED-VPTR: "-fsanitize={{((alignment|array-bounds|bool|builtin|enum|float-cast-overflow|integer-divide-by-zero|nonnull-attribute|null|pointer-overflow|return|returns-nonnull-attribute|shift-base|shift-exponent|signed-integer-overflow|unreachable|vla-bound|vptr),?){18}"}} // * Test BareMetal toolchain sanitizer support * diff --git a/clang/test/Driver/fveclib.c b/clang/test/Driver/fveclib.c index 09a12c2327137..7d0985c4dd4f4 100644 --- a/clang/test/Driver/fveclib.c +++ b/clang/test/Driver/fveclib.c @@ -112,3 +112,20 @@ /* Verify no warning when math-errno is re-enabled for a different veclib (that does not imply -fno-math-errno). */ // RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL -fmath-errno -fveclib=LIBMVEC %s 2>&1 | FileCheck --check-prefix=CHECK-REPEAT-VECLIB %s // CHECK-REPEAT-VECLIB-NOT: math errno enabled + +/// Verify that vectorized routines library is being linked in. +// RUN: %clang -### --target=aarch64-pc-windows-msvc -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-MSVC %s +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-LINUX %s +// RUN: %clang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s -lamath 2>&1 | FileCheck --check-prefix=CHECK-LINKING-AMATH-BEFORE-ARMPL-LINUX %s +// RUN: %clang -### --target=arm64-apple-darwin -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-DARWIN %s +// RUN: %clang -### --target=arm64-apple-darwin -fveclib=ArmPL %s -lamath 2>&1 | FileCheck --check-prefix=CHECK-LINKING-AMATH-BEFORE-ARMPL-DARWIN %s +// CHECK-LINKING-ARMPL-LINUX: "--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state" +// CHECK-LINKING-ARMPL-DARWIN: "-lm" "-lamath" "-lm" +// CHECK-LINKING-ARMPL-MSVC: "--dependent-lib=amath" +// CHECK-LINKING-AMATH-BEFORE-ARMPL-LINUX: "-lamath" {{.*}}"--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state" +// CHECK-LINKING-AMATH-BEFORE-ARMPL-DARWIN: "-lamath" {{.*}}"-lm" "-lamath" "-lm" + +/// Verify that the RPATH is being set when needed. +// RUN: %clang -### --target=aarch64-linux-gnu -resource-dir=%S/../../../clang/test/Driver/Inputs/resource_dir_with_arch_subdir -frtlib-add-rpath -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-RPATH-ARMPL %s +// CHECK-RPATH-ARMPL: "--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state" +// CHECK-RPATH-ARMPL-SAME: "-rpath" diff --git a/clang/test/Driver/module-fgen-reduced-bmi.cppm b/clang/test/Driver/module-fgen-reduced-bmi.cppm index 1223189fb49b7..7329c12941d73 100644 --- a/clang/test/Driver/module-fgen-reduced-bmi.cppm +++ b/clang/test/Driver/module-fgen-reduced-bmi.cppm @@ -29,13 +29,41 @@ // // RUN: %clang -std=c++20 Hello.cc -fexperimental-modules-reduced-bmi -Wall -Werror \ // RUN: -c -o Hello.o -### 2>&1 | FileCheck Hello.cc +// +// RUN: %clang -std=c++20 Hello.cppm -fmodule-output=Hello.pcm \ +// RUN: -fmodules-reduced-bmi -c -o Hello.o -### 2>&1 | FileCheck Hello.cppm +// +// RUN: %clang -std=c++20 Hello.cppm \ +// RUN: -fmodules-reduced-bmi -c -o Hello.o -### 2>&1 | \ +// RUN: FileCheck Hello.cppm --check-prefix=CHECK-UNSPECIFIED +// +// RUN: %clang -std=c++20 Hello.cppm \ +// RUN: -fmodules-reduced-bmi -c -### 2>&1 | \ +// RUN: FileCheck Hello.cppm --check-prefix=CHECK-NO-O +// +// RUN: %clang -std=c++20 Hello.cppm \ +// RUN: -fmodules-reduced-bmi -c -o AnotherName.o -### 2>&1 | \ +// RUN: FileCheck Hello.cppm --check-prefix=CHECK-ANOTHER-NAME +// +// RUN: %clang -std=c++20 Hello.cppm --precompile -fmodules-reduced-bmi \ +// RUN: -o Hello.full.pcm -### 2>&1 | FileCheck Hello.cppm \ +// RUN: --check-prefix=CHECK-EMIT-MODULE-INTERFACE +// +// RUN: %clang -std=c++20 Hello.cc -fmodules-reduced-bmi -Wall -Werror \ +// RUN: -c -o Hello.o -### 2>&1 | FileCheck Hello.cc +// +// RUN: %clang -std=c++20 Hello.cppm -fmodule-output=Hello.pcm -c -o Hello.o \ +// RUN: -Wno-missing-reduced-bmi -### 2>&1 | FileCheck Hello.cppm -check-prefix=NO_WARN +// +// RUN: %clang -std=c++20 Hello.cppm --precompile -o Hello.pcm \ +// RUN: -Wno-missing-reduced-bmi -### 2>&1 | FileCheck Hello.cppm -check-prefix=NO_WARN //--- Hello.cppm export module Hello; // Test that we won't generate the emit-module-interface as 2 phase compilation model. // CHECK-NOT: -emit-module-interface -// CHECK: "-fexperimental-modules-reduced-bmi" +// CHECK: "-fmodules-reduced-bmi" // CHECK-UNSPECIFIED: -fmodule-output=Hello.pcm @@ -46,6 +74,8 @@ export module Hello; // flag. // CHECK-EMIT-MODULE-INTERFACE: -emit-module-interface +// NO_WARN-NOT: warning + //--- Hello.cc -// CHECK-NOT: "-fexperimental-modules-reduced-bmi" +// CHECK-NOT: "-fmodules-reduced-bmi" diff --git a/clang/test/Driver/openmp-offload.c b/clang/test/Driver/openmp-offload.c index eaed0d66df75c..caedc223a5c76 100644 --- a/clang/test/Driver/openmp-offload.c +++ b/clang/test/Driver/openmp-offload.c @@ -84,9 +84,15 @@ /// Check -Xopenmp-target triggers error when an option requiring arguments is passed to it. // RUN: not %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=powerpc64le-ibm-linux-gnu -Xopenmp-target -Xopenmp-target -mcpu=pwr8 %s 2>&1 \ -// RUN: | FileCheck -check-prefix=CHK-FOPENMP-TARGET-NESTED-ERROR %s +// RUN: | FileCheck -check-prefix=CHK-FOPENMP-TARGET-NESTED-ERROR_0 %s -// CHK-FOPENMP-TARGET-NESTED-ERROR: clang{{.*}} error: invalid -Xopenmp-target argument: '-Xopenmp-target -Xopenmp-target', options requiring arguments are unsupported +// CHK-FOPENMP-TARGET-NESTED-ERROR_0: error: invalid -Xopenmp-target argument: '-Xopenmp-target -Xopenmp-target', options requiring arguments are unsupported + +/// Check -Xopenmp-target= triggers error when an option requiring arguments is passed to it. +// RUN: not %clang -### -no-canonical-prefixes -fopenmp=libomp -fopenmp-targets=powerpc64le-ibm-linux-gnu -Xopenmp-target=powerpc64le-ibm-linux-gnu -Xopenmp-target -mcpu=pwr8 %s 2>&1 \ +// RUN: | FileCheck -check-prefix=CHK-FOPENMP-TARGET-NESTED-ERROR_1 %s + +// CHK-FOPENMP-TARGET-NESTED-ERROR_1: error: invalid -Xopenmp-target argument: '-Xopenmp-target=powerpc64le-ibm-linux-gnu -Xopenmp-target', options requiring arguments are unsupported /// ########################################################################### diff --git a/clang/test/Driver/print-enabled-extensions/aarch64-fujitsu-monaka.c b/clang/test/Driver/print-enabled-extensions/aarch64-fujitsu-monaka.c new file mode 100644 index 0000000000000..3c74e3620df03 --- /dev/null +++ b/clang/test/Driver/print-enabled-extensions/aarch64-fujitsu-monaka.c @@ -0,0 +1,82 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang --target=aarch64 --print-enabled-extensions -mcpu=fujitsu-monaka | FileCheck --strict-whitespace --implicit-check-not=FEAT_ %s + +// CHECK: Extensions enabled for the given AArch64 target +// CHECK-EMPTY: +// CHECK-NEXT: Architecture Feature(s) Description +// CHECK-NEXT: FEAT_AES, FEAT_PMULL Enable AES support +// CHECK-NEXT: FEAT_AMUv1 Enable Armv8.4-A Activity Monitors extension +// CHECK-NEXT: FEAT_AMUv1p1 Enable Armv8.6-A Activity Monitors Virtualization support +// CHECK-NEXT: FEAT_AdvSIMD Enable Advanced SIMD instructions +// CHECK-NEXT: FEAT_BF16 Enable BFloat16 Extension +// CHECK-NEXT: FEAT_BTI Enable Branch Target Identification +// CHECK-NEXT: FEAT_CCIDX Enable Armv8.3-A Extend of the CCSIDR number of sets +// CHECK-NEXT: FEAT_CLRBHB Enable Clear BHB instruction +// CHECK-NEXT: FEAT_CRC32 Enable Armv8.0-A CRC-32 checksum instructions +// CHECK-NEXT: FEAT_CSV2_2 Enable architectural speculation restriction +// CHECK-NEXT: FEAT_DIT Enable Armv8.4-A Data Independent Timing instructions +// CHECK-NEXT: FEAT_DPB Enable Armv8.2-A data Cache Clean to Point of Persistence +// CHECK-NEXT: FEAT_DPB2 Enable Armv8.5-A Cache Clean to Point of Deep Persistence +// CHECK-NEXT: FEAT_DotProd Enable dot product support +// CHECK-NEXT: FEAT_ECV Enable enhanced counter virtualization extension +// CHECK-NEXT: FEAT_ETE Enable Embedded Trace Extension +// CHECK-NEXT: FEAT_FAMINMAX Enable FAMIN and FAMAX instructions +// CHECK-NEXT: FEAT_FCMA Enable Armv8.3-A Floating-point complex number support +// CHECK-NEXT: FEAT_FGT Enable fine grained virtualization traps extension +// CHECK-NEXT: FEAT_FHM Enable FP16 FML instructions +// CHECK-NEXT: FEAT_FP Enable Armv8.0-A Floating Point Extensions +// CHECK-NEXT: FEAT_FP16 Enable half-precision floating-point data processing +// CHECK-NEXT: FEAT_FP8 Enable FP8 instructions +// CHECK-NEXT: FEAT_FP8DOT2 Enable FP8 2-way dot instructions +// CHECK-NEXT: FEAT_FP8DOT4 Enable FP8 4-way dot instructions +// CHECK-NEXT: FEAT_FP8FMA Enable Armv9.5-A FP8 multiply-add instructions +// CHECK-NEXT: FEAT_FPAC Enable Armv8.3-A Pointer Authentication Faulting enhancement +// CHECK-NEXT: FEAT_FRINTTS Enable FRInt[32|64][Z|X] instructions that round a floating-point number to an integer (in FP format) forcing it to fit into a 32- or 64-bit int +// CHECK-NEXT: FEAT_FlagM Enable Armv8.4-A Flag Manipulation instructions +// CHECK-NEXT: FEAT_FlagM2 Enable alternative NZCV format for floating point comparisons +// CHECK-NEXT: FEAT_HBC Enable Armv8.8-A Hinted Conditional Branches Extension +// CHECK-NEXT: FEAT_HCX Enable Armv8.7-A HCRX_EL2 system register +// CHECK-NEXT: FEAT_I8MM Enable Matrix Multiply Int8 Extension +// CHECK-NEXT: FEAT_JSCVT Enable Armv8.3-A JavaScript FP conversion instructions +// CHECK-NEXT: FEAT_LOR Enable Armv8.1-A Limited Ordering Regions extension +// CHECK-NEXT: FEAT_LRCPC Enable support for RCPC extension +// CHECK-NEXT: FEAT_LRCPC2 Enable Armv8.4-A RCPC instructions with Immediate Offsets +// CHECK-NEXT: FEAT_LS64, FEAT_LS64_V, FEAT_LS64_ACCDATA Enable Armv8.7-A LD64B/ST64B Accelerator Extension +// CHECK-NEXT: FEAT_LSE Enable Armv8.1-A Large System Extension (LSE) atomic instructions +// CHECK-NEXT: FEAT_LSE2 Enable Armv8.4-A Large System Extension 2 (LSE2) atomicity rules +// CHECK-NEXT: FEAT_LUT Enable Lookup Table instructions +// CHECK-NEXT: FEAT_MEC Enable Memory Encryption Contexts Extension +// CHECK-NEXT: FEAT_MOPS Enable Armv8.8-A memcpy and memset acceleration instructions +// CHECK-NEXT: FEAT_MPAM Enable Armv8.4-A Memory system Partitioning and Monitoring extension +// CHECK-NEXT: FEAT_NMI, FEAT_GICv3_NMI Enable Armv8.8-A Non-maskable Interrupts +// CHECK-NEXT: FEAT_NV, FEAT_NV2 Enable Armv8.4-A Nested Virtualization Enchancement +// CHECK-NEXT: FEAT_PAN Enable Armv8.1-A Privileged Access-Never extension +// CHECK-NEXT: FEAT_PAN2 Enable Armv8.2-A PAN s1e1R and s1e1W Variants +// CHECK-NEXT: FEAT_PAuth Enable Armv8.3-A Pointer Authentication extension +// CHECK-NEXT: FEAT_PMUv3 Enable Armv8.0-A PMUv3 Performance Monitors extension +// CHECK-NEXT: FEAT_RAS, FEAT_RASv1p1 Enable Armv8.0-A Reliability, Availability and Serviceability Extensions +// CHECK-NEXT: FEAT_RDM Enable Armv8.1-A Rounding Double Multiply Add/Subtract instructions +// CHECK-NEXT: FEAT_RME Enable Realm Management Extension +// CHECK-NEXT: FEAT_RNG Enable Random Number generation instructions +// CHECK-NEXT: FEAT_SB Enable Armv8.5-A Speculation Barrier +// CHECK-NEXT: FEAT_SEL2 Enable Armv8.4-A Secure Exception Level 2 extension +// CHECK-NEXT: FEAT_SHA1, FEAT_SHA256 Enable SHA1 and SHA256 support +// CHECK-NEXT: FEAT_SHA3, FEAT_SHA512 Enable SHA512 and SHA3 support +// CHECK-NEXT: FEAT_SM4, FEAT_SM3 Enable SM3 and SM4 support +// CHECK-NEXT: FEAT_SPECRES Enable Armv8.5-A execution and data prediction invalidation instructions +// CHECK-NEXT: FEAT_SPECRES2 Enable Speculation Restriction Instruction +// CHECK-NEXT: FEAT_SPEv1p2 Enable extra register in the Statistical Profiling Extension +// CHECK-NEXT: FEAT_SSBS, FEAT_SSBS2 Enable Speculative Store Bypass Safe bit +// CHECK-NEXT: FEAT_SVE Enable Scalable Vector Extension (SVE) instructions +// CHECK-NEXT: FEAT_SVE2 Enable Scalable Vector Extension 2 (SVE2) instructions +// CHECK-NEXT: FEAT_SVE_AES, FEAT_SVE_PMULL128 Enable SVE AES and quadword SVE polynomial multiply instructions +// CHECK-NEXT: FEAT_SVE_BitPerm Enable bit permutation SVE2 instructions +// CHECK-NEXT: FEAT_SVE_SHA3 Enable SHA3 SVE2 instructions +// CHECK-NEXT: FEAT_SVE_SM4 Enable SM4 SVE2 instructions +// CHECK-NEXT: FEAT_TLBIOS, FEAT_TLBIRANGE Enable Armv8.4-A TLB Range and Maintenance instructions +// CHECK-NEXT: FEAT_TRBE Enable Trace Buffer Extension +// CHECK-NEXT: FEAT_TRF Enable Armv8.4-A Trace extension +// CHECK-NEXT: FEAT_UAO Enable Armv8.2-A UAO PState +// CHECK-NEXT: FEAT_VHE Enable Armv8.1-A Virtual Host extension +// CHECK-NEXT: FEAT_WFxT Enable Armv8.7-A WFET and WFIT instruction +// CHECK-NEXT: FEAT_XS Enable Armv8.7-A limited-TLB-maintenance instruction \ No newline at end of file diff --git a/clang/test/Driver/print-enabled-extensions/riscv-rocket-rv64.c b/clang/test/Driver/print-enabled-extensions/riscv-rocket-rv64.c index f8dd58cd74d6d..bc99f7775b7e0 100644 --- a/clang/test/Driver/print-enabled-extensions/riscv-rocket-rv64.c +++ b/clang/test/Driver/print-enabled-extensions/riscv-rocket-rv64.c @@ -4,10 +4,10 @@ // Simple litmus test to check the frontend handling of this option is // enabled. -// CHECK: Extensions enabled for the given RISC-V 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: zicsr 2.0 'zicsr' (CSRs) -// CHECK-NEXT: zifencei 2.0 'Zifencei' (fence.i) +// CHECK-NEXT: Name Version Description +// CHECK-NEXT: i 2.1 'I' (Base Integer Instruction Set) +// CHECK-NEXT: zicsr 2.0 'Zicsr' (CSRs) +// CHECK-NEXT: zifencei 2.0 'Zifencei' (fence.i) // CHECK-EMPTY: diff --git a/clang/test/Driver/print-supported-cpus-aarch64.c b/clang/test/Driver/print-supported-cpus-aarch64.c new file mode 100644 index 0000000000000..3c1dcebf7c6c8 --- /dev/null +++ b/clang/test/Driver/print-supported-cpus-aarch64.c @@ -0,0 +1,27 @@ +// Test that --print-supported-cpus lists supported CPU models, including aliases. + +// REQUIRES: aarch64-registered-target + +// RUN: %clang --target=arm64-apple-macosx --print-supported-cpus 2>&1 | \ +// RUN: FileCheck %s --check-prefix=CHECK --implicit-check-not=apple-latest + +// CHECK: Target: arm64-apple-macosx + +// CHECK: apple-a11 +// CHECK: apple-a12 +// CHECK: apple-a13 +// CHECK: apple-a14 +// CHECK: apple-a15 +// CHECK: apple-a16 +// CHECK: apple-a17 +// CHECK: apple-a7 +// CHECK: apple-a8 +// CHECK: apple-a9 +// CHECK: apple-m1 +// CHECK: apple-m2 +// CHECK: apple-m3 +// CHECK: apple-m4 +// CHECK: apple-s4 +// CHECK: apple-s5 + +// CHECK: Use -mcpu or -mtune to specify the target's processor. diff --git a/clang/test/Driver/print-supported-extensions-riscv.c b/clang/test/Driver/print-supported-extensions-riscv.c index 9df903115b57c..8344c1aa39973 100644 --- a/clang/test/Driver/print-supported-extensions-riscv.c +++ b/clang/test/Driver/print-supported-extensions-riscv.c @@ -5,7 +5,7 @@ // CHECK-EMPTY: // CHECK-NEXT: Name Version Description // CHECK-NEXT: i 2.1 'I' (Base Integer Instruction Set) -// CHECK-NEXT: e 2.0 Implements RV{32,64}E (provides 16 rather than 32 GPRs) +// CHECK-NEXT: e 2.0 'E' (Embedded Instruction Set with 16 GPRs) // 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) @@ -24,7 +24,7 @@ // CHECK-NEXT: ziccrse 1.0 'Ziccrse' (Main Memory Supports Forward Progress on LR/SC Sequences) // CHECK-NEXT: zicntr 2.0 'Zicntr' (Base Counters and Timers) // CHECK-NEXT: zicond 1.0 'Zicond' (Integer Conditional Operations) -// CHECK-NEXT: zicsr 2.0 'zicsr' (CSRs) +// CHECK-NEXT: zicsr 2.0 'Zicsr' (CSRs) // CHECK-NEXT: zifencei 2.0 'Zifencei' (fence.i) // CHECK-NEXT: zihintntl 1.0 'Zihintntl' (Non-Temporal Locality Hints) // CHECK-NEXT: zihintpause 2.0 'Zihintpause' (Pause Hint) @@ -78,7 +78,7 @@ // 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: zvfbfmin 1.0 'Zvbfmin' (Vector BF16 Converts) +// CHECK-NEXT: zvfbfmin 1.0 'Zvfbfmin' (Vector BF16 Converts) // CHECK-NEXT: zvfbfwma 1.0 'Zvfbfwma' (Vector BF16 widening mul-add) // CHECK-NEXT: zvfh 1.0 'Zvfh' (Vector Half-Precision Floating-Point) // CHECK-NEXT: zvfhmin 1.0 'Zvfhmin' (Vector Half-Precision Floating-Point Minimal) @@ -87,7 +87,7 @@ // CHECK-NEXT: zvkn 1.0 'Zvkn' (shorthand for 'Zvkned', 'Zvknhb', 'Zvkb', and 'Zvkt') // CHECK-NEXT: zvknc 1.0 'Zvknc' (shorthand for 'Zvknc' and 'Zvbc') // CHECK-NEXT: zvkned 1.0 'Zvkned' (Vector AES Encryption & Decryption (Single Round)) -// CHECK-NEXT: zvkng 1.0 'zvkng' (shorthand for 'Zvkn' and 'Zvkg') +// CHECK-NEXT: zvkng 1.0 'Zvkng' (shorthand for 'Zvkn' and 'Zvkg') // CHECK-NEXT: zvknha 1.0 'Zvknha' (Vector SHA-2 (SHA-256 only)) // CHECK-NEXT: zvknhb 1.0 'Zvknhb' (Vector SHA-2 (SHA-256 and SHA-512)) // CHECK-NEXT: zvks 1.0 'Zvks' (shorthand for 'Zvksed', 'Zvksh', 'Zvkb', and 'Zvkt') @@ -96,25 +96,25 @@ // CHECK-NEXT: zvksg 1.0 'Zvksg' (shorthand for 'Zvks' and 'Zvkg') // CHECK-NEXT: zvksh 1.0 'Zvksh' (SM3 Hash Function Instructions) // CHECK-NEXT: zvkt 1.0 'Zvkt' (Vector Data-Independent Execution Latency) -// CHECK-NEXT: zvl1024b 1.0 'Zvl' (Minimum Vector Length) 1024 -// CHECK-NEXT: zvl128b 1.0 'Zvl' (Minimum Vector Length) 128 -// CHECK-NEXT: zvl16384b 1.0 'Zvl' (Minimum Vector Length) 16384 -// CHECK-NEXT: zvl2048b 1.0 'Zvl' (Minimum Vector Length) 2048 -// CHECK-NEXT: zvl256b 1.0 'Zvl' (Minimum Vector Length) 256 -// CHECK-NEXT: zvl32768b 1.0 'Zvl' (Minimum Vector Length) 32768 -// CHECK-NEXT: zvl32b 1.0 'Zvl' (Minimum Vector Length) 32 -// CHECK-NEXT: zvl4096b 1.0 'Zvl' (Minimum Vector Length) 4096 -// CHECK-NEXT: zvl512b 1.0 'Zvl' (Minimum Vector Length) 512 -// CHECK-NEXT: zvl64b 1.0 'Zvl' (Minimum Vector Length) 64 -// CHECK-NEXT: zvl65536b 1.0 'Zvl' (Minimum Vector Length) 65536 -// CHECK-NEXT: zvl8192b 1.0 'Zvl' (Minimum Vector Length) 8192 +// CHECK-NEXT: zvl1024b 1.0 'Zvl1024b' (Minimum Vector Length 1024) +// CHECK-NEXT: zvl128b 1.0 'Zvl128b' (Minimum Vector Length 128) +// CHECK-NEXT: zvl16384b 1.0 'Zvl16384b' (Minimum Vector Length 16384) +// CHECK-NEXT: zvl2048b 1.0 'Zvl2048b' (Minimum Vector Length 2048) +// CHECK-NEXT: zvl256b 1.0 'Zvl256b' (Minimum Vector Length 256) +// CHECK-NEXT: zvl32768b 1.0 'Zvl32768b' (Minimum Vector Length 32768) +// CHECK-NEXT: zvl32b 1.0 'Zvl32b' (Minimum Vector Length 32) +// CHECK-NEXT: zvl4096b 1.0 'Zvl4096b' (Minimum Vector Length 4096) +// CHECK-NEXT: zvl512b 1.0 'Zvl512b' (Minimum Vector Length 512) +// CHECK-NEXT: zvl64b 1.0 'Zvl64b' (Minimum Vector Length 64) +// CHECK-NEXT: zvl65536b 1.0 'Zvl65536b' (Minimum Vector Length 65536) +// CHECK-NEXT: zvl8192b 1.0 'Zvl8192b' (Minimum Vector Length 8192) // CHECK-NEXT: zhinx 1.0 'Zhinx' (Half Float in Integer) // CHECK-NEXT: zhinxmin 1.0 'Zhinxmin' (Half Float in Integer Minimal) // CHECK-NEXT: sha 1.0 'Sha' (Augmented Hypervisor) // CHECK-NEXT: shcounterenw 1.0 'Shcounterenw' (Support writeable hcounteren enable bit for any hpmcounter that is not read-only zero) -// CHECK-NEXT: shgatpa 1.0 'Sgatpa' (SvNNx4 mode supported for all modes supported by satp, as well as Bare) +// CHECK-NEXT: shgatpa 1.0 'Shgatpa' (SvNNx4 mode supported for all modes supported by satp, as well as Bare) // CHECK-NEXT: shtvala 1.0 'Shtvala' (htval provides all needed values) -// CHECK-NEXT: shvsatpa 1.0 'Svsatpa' (vsatp supports all modes supported by satp) +// CHECK-NEXT: shvsatpa 1.0 'Shvsatpa' (vsatp supports all modes supported by satp) // CHECK-NEXT: shvstvala 1.0 'Shvstvala' (vstval provides all needed values) // CHECK-NEXT: shvstvecd 1.0 'Shvstvecd' (vstvec supports Direct mode) // CHECK-NEXT: smaia 1.0 'Smaia' (Advanced Interrupt Architecture Machine Level) @@ -145,11 +145,11 @@ // CHECK-NEXT: supm 1.0 'Supm' (Indicates User-mode Pointer Masking) // CHECK-NEXT: svade 1.0 'Svade' (Raise exceptions on improper A/D bits) // CHECK-NEXT: svadu 1.0 'Svadu' (Hardware A/D updates) -// CHECK-NEXT: svbare 1.0 'Svbare' $(satp mode Bare supported) +// CHECK-NEXT: svbare 1.0 'Svbare' (satp mode Bare supported) // CHECK-NEXT: svinval 1.0 'Svinval' (Fine-Grained Address-Translation Cache Invalidation) // CHECK-NEXT: svnapot 1.0 'Svnapot' (NAPOT Translation Contiguity) // 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: svvptc 1.0 'Svvptc' (Obviating Memory-Management Instructions after Marking PTEs Valid) // CHECK-NEXT: xcvalu 1.0 'XCValu' (CORE-V ALU Operations) // CHECK-NEXT: xcvbi 1.0 'XCVbi' (CORE-V Immediate Branching) // CHECK-NEXT: xcvbitmanip 1.0 'XCVbitmanip' (CORE-V Bit Manipulation) @@ -189,7 +189,9 @@ // 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: xqcia 0.2 'Xqcia' (Qualcomm uC Arithmetic Extension) +// CHECK-NEXT: xqcics 0.2 'Xqcics' (Qualcomm uC Conditional Select Extension) // CHECK-NEXT: xqcicsr 0.2 'Xqcicsr' (Qualcomm uC CSR Extension) +// CHECK-NEXT: xqcilsm 0.2 'Xqcilsm' (Qualcomm uC Load Store Multiple Extension) // CHECK-NEXT: xqcisls 0.2 'Xqcisls' (Qualcomm uC Scaled Load Store Extension) // CHECK-EMPTY: // CHECK-NEXT: Supported Profiles diff --git a/clang/test/Driver/riscv-cpus.c b/clang/test/Driver/riscv-cpus.c index 249216612f7ee..1b09945620f8c 100644 --- a/clang/test/Driver/riscv-cpus.c +++ b/clang/test/Driver/riscv-cpus.c @@ -98,6 +98,23 @@ // RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=rocket-rv64 | FileCheck -check-prefix=MTUNE-ROCKET64 %s // MTUNE-ROCKET64: "-tune-cpu" "rocket-rv64" +// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mtune=mips-p8700 | FileCheck -check-prefix=MTUNE-MIPS-P8700 %s +// MTUNE-MIPS-P8700: "-tune-cpu" "mips-p8700" + +// RUN: %clang --target=riscv64 -### -c %s 2>&1 -mcpu=mips-p8700 | FileCheck -check-prefix=MCPU-MIPS-P8700 %s +// MCPU-MIPS-P8700: "-target-cpu" "mips-p8700" +// MCPU-MIPS-P8700-SAME: "-target-feature" "+m" +// MCPU-MIPS-P8700-SAME: "-target-feature" "+a" +// MCPU-MIPS-P8700-SAME: "-target-feature" "+f" +// MCPU-MIPS-P8700-SAME: "-target-feature" "+d" +// MCPU-MIPS-P8700-SAME: "-target-feature" "+c" +// MCPU-MIPS-P8700-SAME: "-target-feature" "+zicsr" +// MCPU-MIPS-P8700-SAME: "-target-feature" "+zifencei" +// MCPU-MIPS-P8700-SAME: "-target-feature" "+zaamo" +// MCPU-MIPS-P8700-SAME: "-target-feature" "+zalrsc" +// MCPU-MIPS-P8700-SAME: "-target-feature" "+zba" +// MCPU-MIPS-P8700-SAME: "-target-feature" "+zbb" + // RUN: %clang --target=riscv32 -### -c %s 2>&1 -mtune=syntacore-scr1-base | FileCheck -check-prefix=MTUNE-SYNTACORE-SCR1-BASE %s // MTUNE-SYNTACORE-SCR1-BASE: "-tune-cpu" "syntacore-scr1-base" diff --git a/clang/test/Driver/stack-clash-protection.c b/clang/test/Driver/stack-clash-protection.c index 222452f7897a6..3b0476db9d3cb 100644 --- a/clang/test/Driver/stack-clash-protection.c +++ b/clang/test/Driver/stack-clash-protection.c @@ -22,6 +22,11 @@ // SCP-ll-win64-NOT: attributes {{.*}} "probe-stack"="inline-asm" // SCP-ll-win64: argument unused during compilation: '-fstack-clash-protection' +// RUN: %clang -target x86_64-unknown-fuchsia -fstack-clash-protection -### %s 2>&1 | FileCheck %s -check-prefix=SCP-FUCHSIA +// RUN: %clang -target aarch64-unknown-fuchsia -fstack-clash-protection -### %s 2>&1 | FileCheck %s -check-prefix=SCP-FUCHSIA +// RUN: %clang -target riscv64-unknown-fuchsia -fstack-clash-protection -### %s 2>&1 | FileCheck %s -check-prefix=SCP-FUCHSIA +// SCP-FUCHSIA: "-fstack-clash-protection" + int foo(int c) { int r; __asm__("sub %0, %%rsp" diff --git a/clang/test/Driver/sysroot.c b/clang/test/Driver/sysroot.c index 85da2499090af..3080f76e03168 100644 --- a/clang/test/Driver/sysroot.c +++ b/clang/test/Driver/sysroot.c @@ -4,10 +4,9 @@ // CHECK-SYSROOTEQ: "-cc1"{{.*}} "-isysroot" "{{[^"]*}}/FOO" // Apple Darwin uses -isysroot as the syslib root, too. -// We pass --sysroot="" to defeat any -DDEFAULT_SYSROOT parameter. // RUN: touch %t2.o // RUN: %clang -target i386-apple-darwin10 \ -// RUN: -isysroot /FOO --sysroot="" -### %t2.o 2> %t2 +// RUN: -isysroot /FOO -### %t2.o 2> %t2 // RUN: FileCheck --check-prefix=CHECK-APPLE-ISYSROOT < %t2 %s // CHECK-APPLE-ISYSROOT: "-arch" "i386"{{.*}} "-syslibroot" "{{[^"]*}}/FOO" diff --git a/clang/test/Driver/unknown-arg-drivermodes.test b/clang/test/Driver/unknown-arg-drivermodes.test new file mode 100644 index 0000000000000..a7ea73af345e0 --- /dev/null +++ b/clang/test/Driver/unknown-arg-drivermodes.test @@ -0,0 +1,55 @@ +// RUN: %clang_cl \ +// RUN: --config \ +// RUN: -fdiagnostics-color=auto \ +// RUN: -fno-record-command-line \ +// RUN: -frecord-command-line \ +// RUN: -nodefaultlibs \ +// RUN: -nostdlib \ +// RUN: -rpath \ +// RUN: -shared \ +// RUN: -static \ +// RUN: -stdlib \ +// RUN: -Xoffload-linker \ +// RUN: -### -x c++ -c - < /dev/null 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CL --implicit-check-not="warning:" + +// RUN: not %clang_dxc \ +// RUN: --config \ +// RUN: -fdiagnostics-color=auto \ +// RUN: -fno-record-command-line \ +// RUN: -frecord-command-line \ +// RUN: -nodefaultlibs \ +// RUN: -nostdlib \ +// RUN: -rpath \ +// RUN: -shared \ +// RUN: -static \ +// RUN: -stdlib \ +// RUN: -Xlinker \ +// RUN: -Xoffload-linker \ +// RUN: -### -T lib_6_3 -Vd - < /dev/null 2>&1 \ +// RUN: | FileCheck %s --check-prefix=DXC --implicit-check-not="error:" + +// CL: warning: unknown argument ignored in clang-cl: '--config' +// CL: warning: unknown argument ignored in clang-cl: '-fdiagnostics-color=auto' +// CL: warning: unknown argument ignored in clang-cl: '-fno-record-command-line' +// CL: warning: unknown argument ignored in clang-cl: '-frecord-command-line' +// CL: warning: unknown argument ignored in clang-cl: '-nodefaultlibs' +// CL: warning: unknown argument ignored in clang-cl: '-nostdlib' +// CL: warning: unknown argument ignored in clang-cl: '-rpath' +// CL: warning: unknown argument ignored in clang-cl: '-shared' +// CL: warning: unknown argument ignored in clang-cl: '-static' +// CL: warning: unknown argument ignored in clang-cl: '-stdlib' +// CL: warning: unknown argument ignored in clang-cl: '-Xoffload-linker' + +// DXC: error: unknown argument: '--config' +// DXC: error: unknown argument: '-fdiagnostics-color=auto' +// DXC: error: unknown argument: '-fno-record-command-line' +// DXC: error: unknown argument: '-frecord-command-line' +// DXC: error: unknown argument: '-nodefaultlibs' +// DXC: error: unknown argument: '-nostdlib' +// DXC: error: unknown argument: '-rpath' +// DXC: error: unknown argument: '-shared' +// DXC: error: unknown argument: '-static' +// DXC: error: unknown argument: '-stdlib' +// DXC: error: unknown argument: '-Xlinker' +// DXC: error: unknown argument: '-Xoffload-linker' diff --git a/clang/test/ExtractAPI/objc_external_category.m b/clang/test/ExtractAPI/objc_external_category.m index 8afc92489f28b..1947237d088e8 100644 --- a/clang/test/ExtractAPI/objc_external_category.m +++ b/clang/test/ExtractAPI/objc_external_category.m @@ -46,7 +46,7 @@ @interface ExtInterface // Symbol graph from the build without extension SGFs should be identical to main symbol graph with extension SGFs // RUN: diff %t/symbols/Module.symbols.json %t/ModuleNoExt.symbols.json -// RUN: FileCheck %s --input-file %t/symbols/ExternalModule@Module.symbols.json --check-prefix EXT +// RUN: FileCheck %s --input-file %t/symbols/Module@ExternalModule.symbols.json --check-prefix EXT // EXT-DAG: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(py)Property $ c:objc(cs)ExtInterface" // EXT-DAG: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(im)InstanceMethod $ c:objc(cs)ExtInterface" // EXT-DAG: "!testRelLabel": "memberOf $ c:objc(cs)ExtInterface(cm)ClassMethod $ c:objc(cs)ExtInterface" @@ -55,3 +55,10 @@ @interface ExtInterface // EXT-DAG: "!testLabel": "c:objc(cs)ExtInterface(cm)ClassMethod" // EXT-NOT: "!testLabel": "c:objc(cs)ExtInterface" // EXT-NOT: "!testLabel": "c:objc(cs)ModInterface" + +// Ensure that the 'module' metadata for the extension symbol graph should still reference the +// declaring module + +// RUN: FileCheck %s --input-file %t/symbols/Module@ExternalModule.symbols.json --check-prefix META +// META: "module": { +// META-NEXT: "name": "Module", diff --git a/clang/test/Format/docs_updated.test b/clang/test/Format/docs_updated.test index fe2e4f1bd13a1..98d330e37ef45 100644 --- a/clang/test/Format/docs_updated.test +++ b/clang/test/Format/docs_updated.test @@ -1,2 +1,6 @@ -// RUN: %python %S/../../docs/tools/dump_format_style.py %t -// RUN: diff %t %S/../../docs/ClangFormatStyleOptions.rst +// RUN: %python %S/../../docs/tools/dump_format_style.py -o %t.style +// RUN: diff --strip-trailing-cr %t.style \ +// RUN: %S/../../docs/ClangFormatStyleOptions.rst + +// RUN: %python %S/../../docs/tools/dump_format_help.py -o %t.help +// RUN: diff --strip-trailing-cr %t.help %S/../../docs/ClangFormat.rst diff --git a/clang/test/Headers/crash-instantiated-in-scope-cxx-modules4.cpp b/clang/test/Headers/crash-instantiated-in-scope-cxx-modules4.cpp new file mode 100644 index 0000000000000..087eb135dc5f5 --- /dev/null +++ b/clang/test/Headers/crash-instantiated-in-scope-cxx-modules4.cpp @@ -0,0 +1,110 @@ +// RUN: rm -fR %t +// RUN: split-file %s %t +// RUN: cd %t +// RUN: %clang_cc1 -verify -std=c++20 -x c++ -fmodule-map-file=modules.map -fmodule-name=foo1 -emit-module modules.map -o foo1.pcm +// RUN: %clang_cc1 -verify -std=c++20 -x c++ -fmodule-map-file=modules.map -fmodule-name=foo2 -emit-module modules.map -o foo2.pcm +// RUN: %clang_cc1 -verify -std=c++20 -x c++ -fmodule-map-file=modules.map -fmodule-file=foo1.pcm -fmodule-file=foo2.pcm server.cc + +//--- functional +#pragma once + +namespace std { +template class function {}; +} // namespace std + +//--- foo.h +#pragma once + +class MethodHandler { + public: + virtual ~MethodHandler() {} + struct HandlerParameter { + HandlerParameter(); + }; + virtual void RunHandler(const HandlerParameter ¶m); +}; + +template +class CallbackUnaryHandler : public MethodHandler { + public: + explicit CallbackUnaryHandler(); + + void RunHandler(const HandlerParameter ¶m) final { + void *call = nullptr; + (void)[call](bool){}; + } +}; + +//--- foo1.h +// expected-no-diagnostics +#pragma once + +#include "functional" + +#include "foo.h" + +class A; + +class ClientAsyncResponseReaderHelper { + public: + using t = std::function; + static void SetupRequest(t finish); +}; + +//--- foo2.h +// expected-no-diagnostics +#pragma once + +#include "foo.h" + +template +class a : public BaseClass { + public: + a() { [[maybe_unused]] CallbackUnaryHandler a; } +}; + +//--- modules.map +module "foo" { + export * + module "foo.h" { + export * + textual header "foo.h" + } +} + +module "foo1" { + export * + module "foo1.h" { + export * + header "foo1.h" + } + + use "foo" +} + +module "foo2" { + export * + module "foo2.h" { + export * + header "foo2.h" + } + + use "foo" +} + +//--- server.cc +// expected-no-diagnostics +#include "functional" + +#include "foo1.h" +#include "foo2.h" + +std::function on_emit; + +template +class CallbackUnaryHandler; + +class s {}; +class hs final : public a { + explicit hs() {} +}; diff --git a/clang/test/Index/print-type.cpp b/clang/test/Index/print-type.cpp index b64469e921a8d..35bf511303332 100644 --- a/clang/test/Index/print-type.cpp +++ b/clang/test/Index/print-type.cpp @@ -163,7 +163,7 @@ inline namespace InlineNS {} // CHECK: DeclRefExpr=i:44:14 [type=int] [typekind=Int] [isPOD=1] // CHECK: StructDecl=Blob:46:8 (Definition) [type=Blob] [typekind=Record] [isPOD=1] [nbFields=2] // CHECK: FieldDecl=i:47:7 (Definition) [type=int] [typekind=Int] [isPOD=1] -// CHECK: VarDecl=member_pointer:50:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [isPOD=1] +// CHECK: VarDecl=member_pointer:50:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [canonicaltype=int Blob::*] [canonicaltypekind=MemberPointer] [isPOD=1] // CHECK: FunctionDecl=elaboratedNamespaceType:52:42 [type=NS::Type (const NS::Type)] [typekind=FunctionProto] [canonicaltype=NS::Type (NS::Type)] [canonicaltypekind=FunctionProto] [resulttype=NS::Type] [resulttypekind=Elaborated] [args= [const NS::Type] [Elaborated]] [isPOD=0] // CHECK: NamespaceRef=NS:52:11 [type=] [typekind=Invalid] [isPOD=0] // CHECK: TypeRef=struct NS::Type:52:23 [type=NS::Type] [typekind=Record] [isPOD=1] diff --git a/clang/test/Layout/ms-x86-member-pointers.cpp b/clang/test/Layout/ms-x86-member-pointers.cpp index a45359f23a9c4..3952226e7d787 100644 --- a/clang/test/Layout/ms-x86-member-pointers.cpp +++ b/clang/test/Layout/ms-x86-member-pointers.cpp @@ -17,56 +17,56 @@ struct UF { char a; int (U::*mp)(); }; // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct SD // CHECK-NEXT: 0 | char a -// CHECK-NEXT: 4 | int struct S::* mp +// CHECK-NEXT: 4 | int S::* mp // CHECK-NEXT: | [sizeof=8, align=4 // CHECK-NEXT: | nvsize=8, nvalign=4] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct MD // CHECK-NEXT: 0 | char a -// CHECK-NEXT: 4 | int struct M::* mp +// CHECK-NEXT: 4 | int M::* mp // CHECK-NEXT: | [sizeof=8, align=4 // CHECK-NEXT: | nvsize=8, nvalign=4] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct VD // CHECK-NEXT: 0 | char a -// CHECK-NEXT: 8 | int struct V::* mp +// CHECK-NEXT: 8 | int V::* mp // CHECK-NEXT: | [sizeof=16, align=8 // CHECK-NEXT: | nvsize=16, nvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct UD // CHECK-NEXT: 0 | char a -// CHECK-NEXT: 8 | int struct U::* mp +// CHECK-NEXT: 8 | int U::* mp // CHECK-NEXT: | [sizeof=24, align=8 // CHECK-NEXT: | nvsize=24, nvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct SF // CHECK-NEXT: 0 | char a -// CHECK-NEXT: 4 | int (struct S::*)(void) __attribute__((thiscall)) mp +// CHECK-NEXT: 4 | int (S::*)(void) __attribute__((thiscall)) mp // CHECK-NEXT: | [sizeof=8, align=4 // CHECK-NEXT: | nvsize=8, nvalign=4] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct MF // CHECK-NEXT: 0 | char a -// CHECK-NEXT: 8 | int (struct M::*)(void) __attribute__((thiscall)) mp +// CHECK-NEXT: 8 | int (M::*)(void) __attribute__((thiscall)) mp // CHECK-NEXT: | [sizeof=16, align=8 // CHECK-NEXT: | nvsize=16, nvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct VF // CHECK-NEXT: 0 | char a -// CHECK-NEXT: 8 | int (struct V::*)(void) __attribute__((thiscall)) mp +// CHECK-NEXT: 8 | int (V::*)(void) __attribute__((thiscall)) mp // CHECK-NEXT: | [sizeof=24, align=8 // CHECK-NEXT: | nvsize=24, nvalign=8] // CHECK: *** Dumping AST Record Layout // CHECK-NEXT: 0 | struct UF // CHECK-NEXT: 0 | char a -// CHECK-NEXT: 8 | int (struct U::*)(void) __attribute__((thiscall)) mp +// CHECK-NEXT: 8 | int (U::*)(void) __attribute__((thiscall)) mp // CHECK-NEXT: | [sizeof=24, align=8 // CHECK-NEXT: | nvsize=24, nvalign=8] diff --git a/clang/test/Misc/target-invalid-cpu-note/aarch64.c b/clang/test/Misc/target-invalid-cpu-note/aarch64.c index ab83f299ac599..e6ff09557fe07 100644 --- a/clang/test/Misc/target-invalid-cpu-note/aarch64.c +++ b/clang/test/Misc/target-invalid-cpu-note/aarch64.c @@ -67,6 +67,7 @@ // CHECK-SAME: {{^}}, exynos-m4 // CHECK-SAME: {{^}}, exynos-m5 // CHECK-SAME: {{^}}, falkor +// CHECK-SAME: {{^}}, fujitsu-monaka // CHECK-SAME: {{^}}, generic // CHECK-SAME: {{^}}, grace // CHECK-SAME: {{^}}, kryo diff --git a/clang/test/Misc/target-invalid-cpu-note/arm.c b/clang/test/Misc/target-invalid-cpu-note/arm.c index 17280a9edd221..12acdabbb7756 100644 --- a/clang/test/Misc/target-invalid-cpu-note/arm.c +++ b/clang/test/Misc/target-invalid-cpu-note/arm.c @@ -84,6 +84,7 @@ // CHECK-SAME: {{^}}, cortex-a78 // CHECK-SAME: {{^}}, cortex-a78ae // CHECK-SAME: {{^}}, cortex-a78c +// CHECK-SAME: {{^}}, cortex-a510 // CHECK-SAME: {{^}}, cortex-a710 // CHECK-SAME: {{^}}, cortex-x1 // CHECK-SAME: {{^}}, cortex-x1c diff --git a/clang/test/Misc/target-invalid-cpu-note/riscv.c b/clang/test/Misc/target-invalid-cpu-note/riscv.c index 8c5df5884cd79..fc8536d99cb80 100644 --- a/clang/test/Misc/target-invalid-cpu-note/riscv.c +++ b/clang/test/Misc/target-invalid-cpu-note/riscv.c @@ -25,6 +25,7 @@ // RISCV64: error: unknown target CPU 'not-a-cpu' // RISCV64-NEXT: note: valid target CPU values are: // RISCV64-SAME: {{^}} generic-rv64 +// RISCV64-SAME: {{^}}, mips-p8700 // RISCV64-SAME: {{^}}, rocket-rv64 // RISCV64-SAME: {{^}}, sifive-p450 // RISCV64-SAME: {{^}}, sifive-p470 @@ -72,6 +73,7 @@ // TUNE-RISCV64: error: unknown target CPU 'not-a-cpu' // TUNE-RISCV64-NEXT: note: valid target CPU values are: // TUNE-RISCV64-SAME: {{^}} generic-rv64 +// TUNE-RISCV64-SAME: {{^}}, mips-p8700 // TUNE-RISCV64-SAME: {{^}}, rocket-rv64 // TUNE-RISCV64-SAME: {{^}}, sifive-p450 // TUNE-RISCV64-SAME: {{^}}, sifive-p470 diff --git a/clang/test/Modules/cxx-templates.cpp b/clang/test/Modules/cxx-templates.cpp index b7d5741e69af6..7b41a0b0bfb2c 100644 --- a/clang/test/Modules/cxx-templates.cpp +++ b/clang/test/Modules/cxx-templates.cpp @@ -251,7 +251,7 @@ namespace Std { // CHECK-DUMP: ClassTemplateDecl {{.*}} <{{.*[/\\]}}cxx-templates-common.h:1:1, {{.*}}> col:{{.*}} in cxx_templates_common SomeTemplate // CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate -// CHECK-DUMP-NEXT: TemplateArgument type 'char[2]' +// CHECK-DUMP-NEXT: TemplateArgument type 'char[{{1|2}}]' // CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition // CHECK-DUMP-NEXT: DefinitionData // CHECK-DUMP-NEXT: DefaultConstructor @@ -260,9 +260,9 @@ namespace Std { // CHECK-DUMP-NEXT: CopyAssignment // CHECK-DUMP-NEXT: MoveAssignment // CHECK-DUMP-NEXT: Destructor -// CHECK-DUMP-NEXT: TemplateArgument type 'char[2]' +// CHECK-DUMP-NEXT: TemplateArgument type 'char[{{1|2}}]' // CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} prev {{.*}} SomeTemplate -// CHECK-DUMP-NEXT: TemplateArgument type 'char[1]' +// CHECK-DUMP-NEXT: TemplateArgument type 'char[{{1|2}}]' // CHECK-DUMP: ClassTemplateSpecializationDecl {{.*}} SomeTemplate definition // CHECK-DUMP-NEXT: DefinitionData // CHECK-DUMP-NEXT: DefaultConstructor @@ -271,4 +271,4 @@ namespace Std { // CHECK-DUMP-NEXT: CopyAssignment // CHECK-DUMP-NEXT: MoveAssignment // CHECK-DUMP-NEXT: Destructor -// CHECK-DUMP-NEXT: TemplateArgument type 'char[1]' +// CHECK-DUMP-NEXT: TemplateArgument type 'char[{{1|2}}]' diff --git a/clang/test/Modules/friend-inline-function-body.cpp b/clang/test/Modules/friend-inline-function-body.cpp new file mode 100644 index 0000000000000..478125a795554 --- /dev/null +++ b/clang/test/Modules/friend-inline-function-body.cpp @@ -0,0 +1,111 @@ +// RUN: rm -fR %t +// RUN: split-file %s %t +// RUN: cd %t +// RUN: %clang_cc1 -std=c++20 -fmodule-map-file=modules.map -xc++ -emit-module -fmodule-name=internal modules.map -o internal.pcm +// RUN: %clang_cc1 -std=c++20 -fmodule-map-file=modules.map -xc++ -emit-module -fmodule-name=interface modules.map -o interface.pcm +// RUN: %clang_cc1 -std=c++20 -fmodule-map-file=modules.map -xc++ -emit-module -fmodule-name=foo modules.map -o foo.pcm -fmodule-file=interface.pcm -fmodule-file=internal.pcm +// RUN: %clang_cc1 -std=c++20 -fmodule-map-file=modules.map -O1 -emit-obj main.cc -verify -fmodule-file=foo.pcm + +//--- modules.map +module "interface" { + export * + module "interface.h" { + export * + header "interface.h" + } +} + +module "internal" { + export * + module "internal.h" { + export * + header "internal.h" + } +} + +module "foo" { + export * + module "foo.h" { + export * + header "foo.h" + } +} + +//--- foo.h +#ifndef FOO_H +#define FOO_H + +#include "strong_int.h" + +DEFINE_STRONG_INT_TYPE(CallbackId, int); + +#define CALL_HASH(id) \ + (void)[&]() { AbslHashValue(0, id); }; + +void test(CallbackId id) { + CALL_HASH(id); +} + +#include "internal.h" +#include "interface.h" + +#endif + +//--- interface.h +#ifndef INTERFACE_H +#define INTERFACE_H + +#include "strong_int.h" + +DEFINE_STRONG_INT_TYPE(EndpointToken, int); + +#endif + +//--- internal.h +#ifndef INTERNAL_H +#define INTERNAL_H + +#include "strong_int.h" + +DEFINE_STRONG_INT_TYPE(OrderedListSortKey, int); +DEFINE_STRONG_INT_TYPE(OrderedListId, int); + +#endif + +//--- strong_int.h +#ifndef STRONG_INT_H +#define STRONG_INT_H + +namespace util_intops { + +template +class StrongInt2; + +template +class StrongInt2 { + public: + template + friend H AbslHashValue(H h, const StrongInt2& i) { + return h; + } +}; + +} // namespace util_intops + +#define DEFINE_STRONG_INT_TYPE(type_name, value_type) \ + struct type_name##_strong_int_tag_ {}; \ + typedef ::util_intops::StrongInt2 \ + type_name; + +#endif + +//--- main.cc +// expected-no-diagnostics +#include "foo.h" + +#include "strong_int.h" + +DEFINE_STRONG_INT_TYPE(ArchiveId2, int); +void partial(ArchiveId2 id) { + CALL_HASH(id); +} diff --git a/clang/test/Modules/initializer-list-recognition-through-export-and-linkage-issue-118218.cpp b/clang/test/Modules/initializer-list-recognition-through-export-and-linkage-issue-118218.cpp new file mode 100644 index 0000000000000..e2c796fb103f6 --- /dev/null +++ b/clang/test/Modules/initializer-list-recognition-through-export-and-linkage-issue-118218.cpp @@ -0,0 +1,39 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/std.cppm -emit-module-interface -o %t/std.pcm +// RUN: %clang_cc1 -std=c++20 %t/mod.cppm -fprebuilt-module-path=%t -emit-module-interface -o %t/mod.pcm +// RUN: %clang_cc1 -std=c++20 -fprebuilt-module-path=%t -verify %t/main.cpp + +//--- std.cppm +export module std; + +extern "C++" { + namespace std { + export template + class initializer_list { + const E* _1; + const E* _2; + }; + } +} + +//--- mod.cppm +export module mod; + +import std; + +export struct A { + void func(std::initializer_list) {} +}; + +//--- main.cpp +// expected-no-diagnostics +import std; +import mod; + +int main() { + A{}.func({1,1}); + return 0; +} diff --git a/clang/test/Modules/odr_hash.cpp b/clang/test/Modules/odr_hash.cpp index f1de6b3d433ed..4de0e50dbc0eb 100644 --- a/clang/test/Modules/odr_hash.cpp +++ b/clang/test/Modules/odr_hash.cpp @@ -3084,8 +3084,8 @@ struct S5 { }; #else S5 s5; -// expected-error@second.h:* {{'PointersAndReferences::S5::x' from module 'SecondModule' is not present in definition of 'PointersAndReferences::S5' in module 'FirstModule'}} -// expected-note@first.h:* {{declaration of 'x' does not match}} +// expected-error@first.h:* {{'PointersAndReferences::S5::x' from module 'FirstModule' is not present in definition of 'PointersAndReferences::S5' in module 'SecondModule'}} +// expected-note@second.h:* {{declaration of 'x' does not match}} #endif #if defined(FIRST) diff --git a/clang/test/Modules/prune-non-affecting-module-map-repeated-textual.cpp b/clang/test/Modules/prune-non-affecting-module-map-repeated-textual.cpp new file mode 100644 index 0000000000000..30914056c55fa --- /dev/null +++ b/clang/test/Modules/prune-non-affecting-module-map-repeated-textual.cpp @@ -0,0 +1,104 @@ +// Same as prune-non-affecting-module-map-repeated.cpp, but check that textual-only +// inclusions do not cause duplication of the module map files they are defined in. + +// RUN: rm -rf %t && mkdir %t +// RUN: split-file %s %t + +// RUN: %clang_cc1 -xc++ -fmodules -fno-implicit-modules \ +// RUN: -fmodule-map-file=%t/base.map -fmodule-map-file=%t/mixed.map\ +// RUN: -fmodule-map-file=%t/mod1.map \ +// RUN: -fmodule-name=mod1 -emit-module %t/mod1.map -o %t/mod1.pcm +// RUN: %clang_cc1 -xc++ -fmodules -fno-implicit-modules \ +// RUN: -fmodule-map-file=%t/mixed.map\ +// RUN: -fmodule-name=mixed -emit-module %t/mixed.map -o %t/mixed.pcm +// RUN: %clang_cc1 -xc++ -fmodules -fno-implicit-modules \ +// RUN: -fmodule-map-file=%t/base.map -fmodule-map-file=%t/mod1.map -fmodule-map-file=%t/mod2.map \ +// RUN: -fmodule-file=%t/mod1.pcm -fmodule-file=%t/mixed.pcm \ +// RUN: -fmodule-name=mod2 -emit-module %t/mod2.map -o %t/mod2.pcm +// RUN: %clang_cc1 -xc++ -fmodules -fno-implicit-modules \ +// RUN: -fmodule-map-file=%t/base.map -fmodule-map-file=%t/mod2.map -fmodule-map-file=%t/mod3.map \ +// RUN: -fmodule-file=%t/mod2.pcm -fmodule-file=%t/mixed.pcm \ +// RUN: -fmodule-name=mod3 -emit-module %t/mod3.map -o %t/mod3.pcm +// RUN: %clang_cc1 -xc++ -fmodules -fno-implicit-modules \ +// RUN: -fmodule-map-file=%t/base.map -fmodule-map-file=%t/mod3.map -fmodule-map-file=%t/mod4.map \ +// RUN: -fmodule-file=%t/mod3.pcm \ +// RUN: -fmodule-name=mod4 -emit-module %t/mod4.map -o %t/mod4.pcm +// RUN: %clang_cc1 -xc++ -fmodules -fno-implicit-modules -fmodule-map-file=%t/base.map -fmodule-map-file=%t/mod4.map -fmodule-file=%t/mod4.pcm -fsyntax-only -verify %t/check_slocs.cc + +//--- base.map +module base { textual header "vector.h" } +//--- mixed.map +module mixed { textual header "mixed_text.h" header "mixed_mod.h"} +//--- mod1.map +module mod1 { header "mod1.h" } +//--- mod2.map +module mod2 { header "mod2.h" } +//--- mod3.map +module mod3 { header "mod3.h" } +//--- mod4.map +module mod4 { header "mod4.h" } +//--- check_slocs.cc +#include "mod4.h" +#include "vector.h" +#pragma clang __debug sloc_usage // expected-remark {{source manager location address space usage}} +// expected-note@* {{% of available space}} + +// base.map must only be present once, despite being used in each module. +// Because its location in every module compile should be non-affecting. + +// expected-note@base.map:1 {{file entered 1 time}} + +// different modules use either only textual header from mixed.map or both textual and modular +// headers. Either combination must lead to only 1 use at the end, because the module is ultimately +// in the import chain and any textual uses should not change that. + +// expected-note@mixed.map:1 {{file entered 1 time}} + +// expected-note@* + {{file entered}} + + +//--- vector.h +#ifndef VECTOR_H +#define VECTOR_H +#endif + +//--- mixed_text.h +#ifndef MIXED_TEXT_H +#define MIXED_TEXT_H +#endif +//--- mixed_mod.h +#ifndef MIXED_MOD_H +#define MIXED_MOD_H +#endif + +//--- mod1.h +#ifndef MOD1 +#define MOD1 +#include "vector.h" +#include "mixed_text.h" +int mod1(); +#endif +//--- mod2.h +#ifndef MOD2 +#define MOD2 +#include "vector.h" +#include "mod1.h" +#include "mixed_mod.h" +int mod2(); +#endif +//--- mod3.h +#ifndef MOD3 +#define MOD3 +#include "vector.h" +#include "mod2.h" +#include "mixed_text.h" +#include "mixed_mod.h" +int mod3(); +#endif +//--- mod4.h +#ifndef MOD4 +#define MOD4 +#include "vector.h" +#include "mod3.h" +int mod4(); +#endif diff --git a/clang/test/Modules/recursive-instantiations.cppm b/clang/test/Modules/recursive-instantiations.cppm new file mode 100644 index 0000000000000..d5854b0e647e3 --- /dev/null +++ b/clang/test/Modules/recursive-instantiations.cppm @@ -0,0 +1,40 @@ +// RUN: rm -rf %t +// RUN: mkdir -p %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/type_traits.cppm -emit-module-interface -o %t/type_traits.pcm +// RUN: %clang_cc1 -std=c++20 %t/test.cpp -fprebuilt-module-path=%t -verify + +//--- type_traits.cppm +export module type_traits; + +export template +constexpr bool is_pod_v = __is_pod(T); + +//--- test.cpp +// expected-no-diagnostics +import type_traits; +// Base is either void or wrapper. +template struct wrapper : Base {}; +template <> struct wrapper {}; + +// wrap<0>::type is wrapper, wrap<1>::type is wrapper>, +// and so on. +template +struct wrap { + template + using type = wrapper::template type>; +}; + +template <> +struct wrap<0> { + template + using type = wrapper; +}; + +inline constexpr int kMaxRank = 40; +template +using rank = typename wrap::template type; +using rank_selector_t = rank; + +static_assert(is_pod_v, "Must be POD"); diff --git a/clang/test/OpenMP/target_parallel_ast_print.cpp b/clang/test/OpenMP/target_parallel_ast_print.cpp index 7e27ac7b92ca4..3ee98bc525c1b 100644 --- a/clang/test/OpenMP/target_parallel_ast_print.cpp +++ b/clang/test/OpenMP/target_parallel_ast_print.cpp @@ -38,10 +38,6 @@ struct S { // CHECK: static int TS; // CHECK-NEXT: #pragma omp threadprivate(S::TS) // CHECK-NEXT: } -// CHECK: template<> struct S { -// CHECK: static char TS; -// CHECK-NEXT: #pragma omp threadprivate(S::TS) -// CHECK-NEXT: } template T tmain(T argc, T *argv) { diff --git a/clang/test/OpenMP/target_teams_ast_print.cpp b/clang/test/OpenMP/target_teams_ast_print.cpp index 8338f2a68f922..cc47ae92efac0 100644 --- a/clang/test/OpenMP/target_teams_ast_print.cpp +++ b/clang/test/OpenMP/target_teams_ast_print.cpp @@ -40,10 +40,6 @@ struct S { // CHECK: static int TS; // CHECK-NEXT: #pragma omp threadprivate(S::TS) // CHECK-NEXT: } -// CHECK: template<> struct S { -// CHECK: static long TS; -// CHECK-NEXT: #pragma omp threadprivate(S::TS) -// CHECK-NEXT: } template T tmain(T argc, T *argv) { diff --git a/clang/test/OpenMP/task_ast_print.cpp b/clang/test/OpenMP/task_ast_print.cpp index 2a6b8908a1e2d..30fb7ab75cc87 100644 --- a/clang/test/OpenMP/task_ast_print.cpp +++ b/clang/test/OpenMP/task_ast_print.cpp @@ -87,10 +87,6 @@ struct S { // CHECK: static int TS; // CHECK-NEXT: #pragma omp threadprivate(S::TS) // CHECK-NEXT: } -// CHECK: template<> struct S { -// CHECK: static long TS; -// CHECK-NEXT: #pragma omp threadprivate(S::TS) -// CHECK-NEXT: } template T tmain(T argc, T *argv) { diff --git a/clang/test/OpenMP/taskloop_strictmodifier_codegen.cpp b/clang/test/OpenMP/taskloop_strictmodifier_codegen.cpp index d9591624a08f0..82dd07a1a63bb 100644 --- a/clang/test/OpenMP/taskloop_strictmodifier_codegen.cpp +++ b/clang/test/OpenMP/taskloop_strictmodifier_codegen.cpp @@ -86,7 +86,7 @@ struct S { // CHECK-NEXT: [[TMP18:%.*]] = tail call ptr @__kmpc_omp_task_alloc(ptr nonnull @[[GLOB1]], i32 [[TMP0]], i32 1, i64 80, i64 16, ptr nonnull @.omp_task_entry..6) // CHECK-NEXT: [[TMP19:%.*]] = load ptr, ptr [[TMP18]], align 8, !tbaa [[TBAA20:![0-9]+]] // CHECK-NEXT: store ptr [[ARGC_ADDR]], ptr [[TMP19]], align 8, !tbaa [[TBAA23:![0-9]+]] -// CHECK-NEXT: [[AGG_CAPTURED3_SROA_2_0__SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[TMP19]], i64 8 +// CHECK-NEXT: [[AGG_CAPTURED3_SROA_2_0__SROA_IDX:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP19]], i64 8 // CHECK-NEXT: store ptr [[ARGV_ADDR]], ptr [[AGG_CAPTURED3_SROA_2_0__SROA_IDX]], align 8, !tbaa [[TBAA25:![0-9]+]] // CHECK-NEXT: [[TMP20:%.*]] = load i32, ptr [[ARGC_ADDR]], align 4, !tbaa [[TBAA3]] // CHECK-NEXT: [[TOBOOL:%.*]] = icmp ne i32 [[TMP20]], 0 @@ -144,7 +144,7 @@ struct S { // CHECK-NEXT: [[TMP4:%.*]] = tail call ptr @__kmpc_omp_task_alloc(ptr nonnull @[[GLOB1]], i32 [[TMP0]], i32 1, i64 80, i64 16, ptr nonnull @.omp_task_entry..10) // CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[TMP4]], align 8, !tbaa [[TBAA20]] // CHECK-NEXT: store ptr [[THIS]], ptr [[TMP5]], align 8, !tbaa [[TBAA37:![0-9]+]] -// CHECK-NEXT: [[AGG_CAPTURED_SROA_2_0__SROA_IDX:%.*]] = getelementptr inbounds i8, ptr [[TMP5]], i64 8 +// CHECK-NEXT: [[AGG_CAPTURED_SROA_2_0__SROA_IDX:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP5]], i64 8 // CHECK-NEXT: store ptr [[C_ADDR]], ptr [[AGG_CAPTURED_SROA_2_0__SROA_IDX]], align 8, !tbaa [[TBAA23]] // CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds nuw i8, ptr [[TMP4]], i64 40 // CHECK-NEXT: store i64 0, ptr [[TMP6]], align 8, !tbaa [[TBAA15]] diff --git a/clang/test/OpenMP/teams_ast_print.cpp b/clang/test/OpenMP/teams_ast_print.cpp index 0087f71ac9f74..597a9b2bdbdc5 100644 --- a/clang/test/OpenMP/teams_ast_print.cpp +++ b/clang/test/OpenMP/teams_ast_print.cpp @@ -27,10 +27,6 @@ struct S { // CHECK: static int TS; // CHECK-NEXT: #pragma omp threadprivate(S::TS) // CHECK-NEXT: } -// CHECK: template<> struct S { -// CHECK: static long TS; -// CHECK-NEXT: #pragma omp threadprivate(S::TS) -// CHECK-NEXT: } template T tmain(T argc, T *argv) { diff --git a/clang/test/Parser/cxx0x-decl.cpp b/clang/test/Parser/cxx0x-decl.cpp index a0b3266c738ff..6d4f16c6f533e 100644 --- a/clang/test/Parser/cxx0x-decl.cpp +++ b/clang/test/Parser/cxx0x-decl.cpp @@ -214,6 +214,7 @@ struct MemberComponentOrder : Base { void NoMissingSemicolonHere(struct S [3]); template void NoMissingSemicolonHereEither(struct S... [N]); +// expected-warning@-1 {{'S...[N]' is no longer a pack expansion but a pack indexing type; add a name to specify a pack expansion}} \ // expected-error@-1 {{'S' does not refer to the name of a parameter pack}} \ // expected-error@-1 {{declaration of anonymous struct must be a definition}} \ // expected-error@-1 {{expected parameter declarator}} \ diff --git a/clang/test/Parser/cxx1z-decomposition.cpp b/clang/test/Parser/cxx1z-decomposition.cpp index 4b17f72effb0f..acf3f99069185 100644 --- a/clang/test/Parser/cxx1z-decomposition.cpp +++ b/clang/test/Parser/cxx1z-decomposition.cpp @@ -110,7 +110,7 @@ namespace BadSpecifiers { int [5] arr = {0}; // expected-error {{place the brackets after the name}} auto *[f] = s; // expected-error {{cannot be declared with type 'auto *'}} expected-error {{incompatible initializer}} - auto S::*[g] = s; // expected-error {{cannot be declared with type 'auto BadSpecifiers::S::*'}} expected-error {{incompatible initializer}} + auto S::*[g] = s; // expected-error {{cannot be declared with type 'auto S::*'}} expected-error {{incompatible initializer}} // ref-qualifiers are OK. auto &&[ok_1] = S(); diff --git a/clang/test/Parser/cxx2c-pack-indexing.cpp b/clang/test/Parser/cxx2c-pack-indexing.cpp index c279bdd7af8c4..72e286322fa97 100644 --- a/clang/test/Parser/cxx2c-pack-indexing.cpp +++ b/clang/test/Parser/cxx2c-pack-indexing.cpp @@ -12,8 +12,7 @@ struct S { // expected-note {{to match this '['}} \ // expected-warning{{declaration does not declare anything}} - T...[]; // expected-error{{expected expression}} \ - // expected-warning{{declaration does not declare anything}} + T...[]; // expected-error{{expected member name or ';' after declaration specifiers}} void f(auto... v) { decltype(v...[1]) a = v...[1]; @@ -65,7 +64,7 @@ int main() { } -namespace GH11460 { +namespace GH111460 { template requires( ); // expected-error {{expected expression}} struct SS { @@ -74,3 +73,12 @@ struct SS { } }; } + +namespace GH119072 { + +template +void foo() { + decltype(Ts...[0]::t) value; +} + +} diff --git a/clang/test/Parser/gh110231.cpp b/clang/test/Parser/gh110231.cpp new file mode 100644 index 0000000000000..b1405517505ff --- /dev/null +++ b/clang/test/Parser/gh110231.cpp @@ -0,0 +1,12 @@ +// RUN: seq 100 | xargs -Ifoo %clang_cc1 -std=c++20 -fsyntax-only -verify %s +// expected-no-diagnostics +// This is a regression test for a non-deterministic stack-overflow. + +template < typename > +concept C1 = true; + +template < typename , auto > +concept C2 = true; + +template < C1 auto V, C2< V > auto> +struct S; diff --git a/clang/test/ParserOpenACC/parse-clauses.c b/clang/test/ParserOpenACC/parse-clauses.c index 656b31444a9ee..2e884c472c2ec 100644 --- a/clang/test/ParserOpenACC/parse-clauses.c +++ b/clang/test/ParserOpenACC/parse-clauses.c @@ -4,37 +4,27 @@ void func() { - // expected-warning@+2{{OpenACC clause 'finalize' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'enter data' not yet implemented, pragma ignored}} -#pragma acc enter data finalize - - // expected-warning@+3{{OpenACC clause 'finalize' not yet implemented, clause ignored}} - // expected-warning@+2{{OpenACC clause 'finalize' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'enter data' not yet implemented, pragma ignored}} -#pragma acc enter data finalize finalize - - // expected-warning@+3{{OpenACC clause 'finalize' not yet implemented, clause ignored}} - // expected-error@+2{{invalid OpenACC clause 'invalid'}} - // expected-warning@+1{{OpenACC construct 'enter data' not yet implemented, pragma ignored}} -#pragma acc enter data finalize invalid - - // expected-warning@+3{{OpenACC clause 'finalize' not yet implemented, clause ignored}} - // expected-error@+2{{invalid OpenACC clause 'invalid'}} - // expected-warning@+1{{OpenACC construct 'enter data' not yet implemented, pragma ignored}} -#pragma acc enter data finalize invalid invalid finalize - - // expected-warning@+3{{OpenACC clause 'wait' not yet implemented, clause ignored}} - // expected-warning@+2{{OpenACC clause 'finalize' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'enter data' not yet implemented, pragma ignored}} -#pragma acc enter data wait finalize + // expected-error@+1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} +#pragma acc exit data finalize - // expected-warning@+2{{OpenACC clause 'if_present' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'host_data' not yet implemented, pragma ignored}} + // expected-error@+1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} +#pragma acc exit data finalize finalize + + // expected-error@+2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} + // expected-error@+1{{invalid OpenACC clause 'invalid'}} +#pragma acc exit data finalize invalid + + // expected-error@+2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} + // expected-error@+1{{invalid OpenACC clause 'invalid'}} +#pragma acc exit data finalize invalid invalid finalize + + // expected-error@+1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} +#pragma acc exit data wait finalize + + // expected-error@+1{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} #pragma acc host_data if_present - // expected-warning@+3{{OpenACC clause 'if_present' not yet implemented, clause ignored}} - // expected-warning@+2{{OpenACC clause 'if_present' not yet implemented, clause ignored}} - // expected-warning@+1{{OpenACC construct 'host_data' not yet implemented, pragma ignored}} + // expected-error@+1{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} #pragma acc host_data if_present, if_present // expected-error@+4{{OpenACC clause 'independent' on 'loop' construct conflicts with previous data dependence clause}} @@ -460,13 +450,16 @@ void VarListClauses() { #pragma acc serial present_or_copy(HasMem.MemArr[3:]) for(int i = 0; i < 5;++i) {} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented, clause ignored}} -#pragma acc serial use_device(s.array[s.value] s.array[s.value :5] ), self + // expected-error@+2 2{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} + // expected-error@+1{{expected ','}} +#pragma acc host_data use_device(s.array[s.value] s.array[s.value :5] ), if_present + for(int i = 0; i < 5;++i) {} + + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(s.array[s.value : 5]), if_present for(int i = 0; i < 5;++i) {} - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented, clause ignored}} -#pragma acc serial use_device(s.array[s.value : 5]), self +#pragma acc host_data use_device(HasMem), if_present for(int i = 0; i < 5;++i) {} // expected-error@+1{{expected ','}} @@ -505,14 +498,13 @@ void VarListClauses() { #pragma acc serial attach(IsPointer), self for(int i = 0; i < 5;++i) {} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented, clause ignored}} -#pragma acc serial detach(s.array[s.value] s.array[s.value :5] ), self - for(int i = 0; i < 5;++i) {} + // expected-error@+4{{expected ','}} + // expected-error@+3{{expected pointer in 'detach' clause, type is 'char'}} + // expected-error@+2{{OpenACC sub-array is not allowed here}} + // expected-note@+1{{expected variable of pointer type}} +#pragma acc exit data copyout(s) detach(s.array[s.value] s.array[s.value :5]) - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented, clause ignored}} -#pragma acc serial detach(s.array[s.value : 5], s.value), self - for(int i = 0; i < 5;++i) {} +#pragma acc exit data copyout(s) detach(IsPointer) // expected-error@+1{{expected ','}} #pragma acc serial private(s.array[s.value] s.array[s.value :5] ), self @@ -528,22 +520,11 @@ void VarListClauses() { #pragma acc serial firstprivate(s.array[s.value : 5], s.value), self for(int i = 0; i < 5;++i) {} - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented, clause ignored}} -#pragma acc serial delete(s.array[s.value] s.array[s.value :5] ), self - for(int i = 0; i < 5;++i) {} - - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented, clause ignored}} -#pragma acc serial delete(s.array[s.value : 5], s.value), self - for(int i = 0; i < 5;++i) {} - - // expected-error@+2{{expected ','}} - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented, clause ignored}} -#pragma acc serial use_device(s.array[s.value] s.array[s.value :5] ), self + // expected-error@+1{{expected ','}} +#pragma acc exit data delete(s.array[s.value] s.array[s.value :5] ) async for(int i = 0; i < 5;++i) {} - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented, clause ignored}} -#pragma acc serial use_device(s.array[s.value : 5], s.value), self +#pragma acc exit data delete(s.array[s.value : 5], s.value),async for(int i = 0; i < 5;++i) {} // expected-error@+2{{expected ','}} diff --git a/clang/test/ParserOpenACC/parse-clauses.cpp b/clang/test/ParserOpenACC/parse-clauses.cpp index dc985826a4efe..770bc3b976c96 100644 --- a/clang/test/ParserOpenACC/parse-clauses.cpp +++ b/clang/test/ParserOpenACC/parse-clauses.cpp @@ -34,6 +34,11 @@ void templ() { #pragma acc parallel async for(;;){} + + + T t; +#pragma acc exit data delete(t) + ; } struct S { diff --git a/clang/test/ParserOpenACC/parse-constructs.c b/clang/test/ParserOpenACC/parse-constructs.c index 27b9a6993fd3e..4a6c31cc9b0a9 100644 --- a/clang/test/ParserOpenACC/parse-constructs.c +++ b/clang/test/ParserOpenACC/parse-constructs.c @@ -54,16 +54,16 @@ void func() { // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc kernels clause list for(;;){} - // expected-error@+2{{invalid OpenACC clause 'clause'}} - // expected-warning@+1{{OpenACC construct 'data' not yet implemented, pragma ignored}} + // expected-error@+2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} + // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc data clause list for(;;){} - // expected-error@+2{{invalid OpenACC clause 'clause'}} - // expected-warning@+1{{OpenACC construct 'enter data' not yet implemented, pragma ignored}} + // expected-error@+2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} + // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc enter data clause list for(;;){} - // expected-error@+2{{invalid OpenACC clause 'clause'}} - // expected-warning@+1{{OpenACC construct 'exit data' not yet implemented, pragma ignored}} + // expected-error@+2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} + // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc exit data clause list for(;;){} // expected-error@+1{{invalid OpenACC directive 'enter invalid'}} @@ -78,8 +78,8 @@ void func() { // expected-error@+1{{expected identifier}} #pragma acc exit } for(;;){} - // expected-error@+2{{invalid OpenACC clause 'clause'}} - // expected-warning@+1{{OpenACC construct 'host_data' not yet implemented, pragma ignored}} + // expected-error@+2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} + // expected-error@+1{{invalid OpenACC clause 'clause'}} #pragma acc host_data clause list for(;;){} // expected-error@+1{{invalid OpenACC clause 'clause'}} diff --git a/clang/test/Preprocessor/predefined-arch-macros.c b/clang/test/Preprocessor/predefined-arch-macros.c index 20aa2d4e0a54c..43f3454ed3c35 100644 --- a/clang/test/Preprocessor/predefined-arch-macros.c +++ b/clang/test/Preprocessor/predefined-arch-macros.c @@ -1953,6 +1953,8 @@ // CHECK_GNR_M32: #define __SSSE3__ 1 // CHECK_GNR_M32: #define __TSXLDTRK__ 1 // CHECK_GNR_M32: #define __UINTR__ 1 +// CHECK_GNR_M32-NOT: #define __USERMSR__ 1 +// CHECK_DMR_M32: #define __USERMSR__ 1 // CHECK_GNR_M32: #define __VAES__ 1 // CHECK_GNR_M32: #define __VPCLMULQDQ__ 1 // CHECK_GNR_M32: #define __WAITPKG__ 1 @@ -2061,6 +2063,8 @@ // CHECK_GNR_M64: #define __SSSE3__ 1 // CHECK_GNR_M64: #define __TSXLDTRK__ 1 // CHECK_GNR_M64: #define __UINTR__ 1 +// CHECK_GNR_M64-NOT: #define __USERMSR__ 1 +// CHECK_DMR_M64: #define __USERMSR__ 1 // CHECK_GNR_M64: #define __VAES__ 1 // CHECK_GNR_M64: #define __VPCLMULQDQ__ 1 // CHECK_GNR_M64: #define __WAITPKG__ 1 diff --git a/clang/test/Preprocessor/sycl-macro.cpp b/clang/test/Preprocessor/sycl-macro.cpp index eecddaa09d1c3..a509086f99e41 100644 --- a/clang/test/Preprocessor/sycl-macro.cpp +++ b/clang/test/Preprocessor/sycl-macro.cpp @@ -10,5 +10,5 @@ // CHECK-NOT:#define __SYCL_DEVICE_ONLY__ 1 // CHECK-NOT:#define CL_SYCL_LANGUAGE_VERSION 121 // CHECK-SYCL-STD:#define CL_SYCL_LANGUAGE_VERSION 121 -// CHECK-SYCL-STD-2020:#define SYCL_LANGUAGE_VERSION 202001 +// CHECK-SYCL-STD-2020:#define SYCL_LANGUAGE_VERSION 202012 // CHECK-SYCL:#define __SYCL_DEVICE_ONLY__ 1 diff --git a/clang/test/Sema/Inputs/lifetime-analysis.h b/clang/test/Sema/Inputs/lifetime-analysis.h index 5c151385b1fe5..f888e6ab94bb6 100644 --- a/clang/test/Sema/Inputs/lifetime-analysis.h +++ b/clang/test/Sema/Inputs/lifetime-analysis.h @@ -128,6 +128,11 @@ struct reference_wrapper { template reference_wrapper ref(T& t) noexcept; +template +struct [[gsl::Pointer]] iterator { + T& operator*() const; +}; + struct false_type { static constexpr bool value = false; constexpr operator bool() const noexcept { return value; } diff --git a/clang/test/Sema/aarch64-fixed-global-register.c b/clang/test/Sema/aarch64-fixed-global-register.c index 9b4a422d8c1b2..f66c3475dae38 100644 --- a/clang/test/Sema/aarch64-fixed-global-register.c +++ b/clang/test/Sema/aarch64-fixed-global-register.c @@ -1,4 +1,13 @@ -// RUN: %clang_cc1 -triple aarch64-unknown-none-gnu %s -verify -fsyntax-only +// RUN: %clang_cc1 -triple aarch64-unknown-none-gnu %s -target-feature +reserve-x4 -target-feature +reserve-x15 -verify -verify=no_x18 -fsyntax-only +// RUN: %clang_cc1 -triple aarch64-unknown-android %s -target-feature +reserve-x4 -target-feature +reserve-x15 -verify -fsyntax-only +register int w0 __asm__ ("w0"); +register long x0 __asm__ ("x0"); register char i1 __asm__ ("x15"); // expected-error {{size of register 'x15' does not match variable size}} -register long long l2 __asm__ ("w14"); // expected-error {{size of register 'w14' does not match variable size}} +register long long l2 __asm__ ("w15"); // expected-error {{size of register 'w15' does not match variable size}} +register int w3 __asm__ ("w3"); // expected-error {{register 'w3' unsuitable for global register variables on this target}} +register long x3 __asm__ ("x3"); // expected-error {{register 'x3' unsuitable for global register variables on this target}} +register int w4 __asm__ ("w4"); +register long x4 __asm__ ("x4"); +register int w18 __asm__ ("w18"); // no_x18-error {{register 'w18' unsuitable for global register variables on this target}} +register long x18 __asm__ ("x18"); // no_x18-error {{register 'x18' unsuitable for global register variables on this target}} diff --git a/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_cvt.c b/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_cvt.c index 09a80c9dff03e..c5f03b27016ba 100644 --- a/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_cvt.c +++ b/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_cvt.c @@ -5,7 +5,8 @@ #include -void test_features_sme2_fp8(svmfloat8_t zn, fpm_t fpmr) __arm_streaming { +void test_features_sme2_fp8(svmfloat8_t zn, svfloat16x2_t znf16, svbfloat16x2_t znbf16, + svfloat32x4_t znf32, fpm_t fpmr) __arm_streaming { // expected-error@+1 {{'svcvtl1_f16_mf8_x2_fpm' needs target feature sme,sme2,fp8}} svcvtl1_f16_mf8_x2_fpm(zn, fpmr); // expected-error@+1 {{'svcvtl2_f16_mf8_x2_fpm' needs target feature sme,sme2,fp8}} @@ -14,4 +15,22 @@ void test_features_sme2_fp8(svmfloat8_t zn, fpm_t fpmr) __arm_streaming { svcvtl1_bf16_mf8_x2_fpm(zn, fpmr); // expected-error@+1 {{'svcvtl2_bf16_mf8_x2_fpm' needs target feature sme,sme2,fp8}} svcvtl2_bf16_mf8_x2_fpm(zn, fpmr); + + // expected-error@+1 {{'svcvt1_f16_mf8_x2_fpm' needs target feature sme,sme2,fp8}} + svcvt1_f16_mf8_x2_fpm(zn, fpmr); + // expected-error@+1 {{'svcvt2_f16_mf8_x2_fpm' needs target feature sme,sme2,fp8}} + svcvt2_f16_mf8_x2_fpm(zn, fpmr); + // expected-error@+1 {{'svcvt1_bf16_mf8_x2_fpm' needs target feature sme,sme2,fp8}} + svcvt1_bf16_mf8_x2_fpm(zn, fpmr); + // expected-error@+1 {{'svcvt2_bf16_mf8_x2_fpm' needs target feature sme,sme2,fp8}} + svcvt2_bf16_mf8_x2_fpm(zn, fpmr); + + // expected-error@+1 {{'svcvt_mf8_f16_x2_fpm' needs target feature sme,sme2,fp8}} + svcvt_mf8_f16_x2_fpm(znf16, fpmr); + // expected-error@+1 {{'svcvt_mf8_bf16_x2_fpm' needs target feature sme,sme2,fp8}} + svcvt_mf8_bf16_x2_fpm(znbf16, fpmr); + // expected-error@+1 {{'svcvt_mf8_f32_x4_fpm' needs target feature sme,sme2,fp8}} + svcvt_mf8_f32_x4_fpm(znf32, fpmr); + // expected-error@+1 {{'svcvtn_mf8_f32_x4_fpm' needs target feature sme,sme2,fp8}} + svcvtn_mf8_f32_x4_fpm(znf32, fpmr); } \ No newline at end of file diff --git a/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_imm.c b/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_imm.c new file mode 100644 index 0000000000000..bea0b29bcc70a --- /dev/null +++ b/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_imm.c @@ -0,0 +1,52 @@ +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -target-feature +sme2 -target-feature +sme-f8f16 -target-feature +sme-f8f32 -fsyntax-only -verify %s + +// REQUIRES: aarch64-registered-target + +#include + +void test_svmopa(svbool_t pn, svbool_t pm, svmfloat8_t zn, svmfloat8_t zm, + fpm_t fpmr) __arm_streaming __arm_inout("za") { + // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 1]}} + svmopa_za16_mf8_m_fpm(-1, pn, pm, zn, zm, fpmr); + // expected-error@+1 {{argument value 2 is outside the valid range [0, 1]}} + svmopa_za16_mf8_m_fpm(2, pn, pm, zn, zm, fpmr); + + // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 3]}} + svmopa_za32_mf8_m_fpm(-1, pn, pm, zn, zm, fpmr); + // expected-error@+1 {{argument value 4 is outside the valid range [0, 3]}} + svmopa_za32_mf8_m_fpm(4, pn, pm, zn, zm, fpmr); +} + +void test_svmla(uint32_t slice, svmfloat8_t zn, svmfloat8x2_t znx2, svmfloat8x4_t znx4, + fpm_t fpmr) __arm_streaming __arm_inout("za") { + // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 15]}} + svmla_lane_za16_mf8_vg2x1_fpm(slice, zn, zn, -1, fpmr); + // expected-error@+1 {{argument value 16 is outside the valid range [0, 15]}} + svmla_lane_za16_mf8_vg2x1_fpm(slice, zn, zn, 16, fpmr); + + // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 15]}} + svmla_lane_za16_mf8_vg2x2_fpm(slice, znx2, zn, -1, fpmr); + // expected-error@+1 {{argument value 16 is outside the valid range [0, 15]}} + svmla_lane_za16_mf8_vg2x2_fpm(slice, znx2, zn, 16, fpmr); + + // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 15]}} + svmla_lane_za16_mf8_vg2x4_fpm(slice, znx4, zn, -1, fpmr); + // expected-error@+1 {{argument value 16 is outside the valid range [0, 15]}} + svmla_lane_za16_mf8_vg2x4_fpm(slice, znx4, zn, 16, fpmr); + + // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 15]}} + svmla_lane_za32_mf8_vg4x1_fpm(slice, zn, zn, -1, fpmr); + // expected-error@+1 {{argument value 16 is outside the valid range [0, 15]}} + svmla_lane_za32_mf8_vg4x1_fpm(slice, zn, zn, 16, fpmr); + + // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 15]}} + svmla_lane_za32_mf8_vg4x2_fpm(slice, znx2, zn, -1, fpmr); + // expected-error@+1 {{argument value 16 is outside the valid range [0, 15]}} + svmla_lane_za32_mf8_vg4x2_fpm(slice, znx2, zn, 16, fpmr); + + // expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 15]}} + svmla_lane_za32_mf8_vg4x4_fpm(slice, znx4, zn, -1, fpmr); + // expected-error@+1 {{argument value 16 is outside the valid range [0, 15]}} + svmla_lane_za32_mf8_vg4x4_fpm(slice, znx4, zn, 16, fpmr); + +} \ No newline at end of file diff --git a/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_mla.c b/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_mla.c new file mode 100644 index 0000000000000..25255f1f469b2 --- /dev/null +++ b/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_mla.c @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -verify -emit-llvm-only %s + +// REQUIRES: aarch64-registered-target + +#include + +void test_svmla(uint32_t slice, svmfloat8_t zn, svmfloat8x2_t znx2, svmfloat8x4_t znx4, + fpm_t fpmr) __arm_streaming __arm_inout("za") { + // expected-error@+1 {{'svmla_lane_za16_mf8_vg2x1_fpm' needs target feature sme,sme-f8f16}} + svmla_lane_za16_mf8_vg2x1_fpm(slice, zn, zn, 0, fpmr); + + // expected-error@+1 {{'svmla_lane_za16_mf8_vg2x2_fpm' needs target feature sme,sme-f8f16}} + svmla_lane_za16_mf8_vg2x2_fpm(slice, znx2, zn, 0, fpmr); + + // expected-error@+1 {{'svmla_lane_za16_mf8_vg2x4_fpm' needs target feature sme,sme-f8f16}} + svmla_lane_za16_mf8_vg2x4_fpm(slice, znx4, zn, 0, fpmr); + + // expected-error@+1 {{'svmla_lane_za32_mf8_vg4x1_fpm' needs target feature sme,sme-f8f32}} + svmla_lane_za32_mf8_vg4x1_fpm(slice, zn, zn, 0, fpmr); + + // expected-error@+1 {{'svmla_lane_za32_mf8_vg4x2_fpm' needs target feature sme,sme-f8f32}} + svmla_lane_za32_mf8_vg4x2_fpm(slice, znx2, zn, 0, fpmr); + + // expected-error@+1 {{'svmla_lane_za32_mf8_vg4x4_fpm' needs target feature sme,sme-f8f32}} + svmla_lane_za32_mf8_vg4x4_fpm(slice, znx4, zn, 0, fpmr); +} \ No newline at end of file diff --git a/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_mopa.c b/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_mopa.c new file mode 100644 index 0000000000000..86426abcd4329 --- /dev/null +++ b/clang/test/Sema/aarch64-fp8-intrinsics/acle_sme2_fp8_mopa.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple aarch64 -target-feature +sme -verify -emit-llvm-only %s + +// REQUIRES: aarch64-registered-target + +#include + +void test_features(svbool_t pn, svbool_t pm, svmfloat8_t zn, svmfloat8_t zm, + fpm_t fpmr) __arm_streaming __arm_inout("za") { + // expected-error@+1 {{'svmopa_za16_mf8_m_fpm' needs target feature sme,sme-f8f16}} + svmopa_za16_mf8_m_fpm(0, pn, pm, zn, zm, fpmr); + // expected-error@+1 {{'svmopa_za32_mf8_m_fpm' needs target feature sme,sme-f8f32}} + svmopa_za32_mf8_m_fpm(0, pn, pm, zn, zm, fpmr); +} diff --git a/clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_fp8_fdot.c b/clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_fp8_fdot.c new file mode 100644 index 0000000000000..bbcd0335ff555 --- /dev/null +++ b/clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_fp8_fdot.c @@ -0,0 +1,54 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -verify -emit-llvm -o - %s + +// REQUIRES: aarch64-registered-target + +#include + +void test_features(uint32_t slice, svmfloat8_t f8, svmfloat8x2_t f8x2, + svmfloat8x4_t f8x4, uint64_t fpmr) __arm_streaming __arm_inout("za") { + // expected-error@+1 {{'svdot_lane_za32_mf8_vg1x2_fpm' needs target feature sme,sme-f8f32}} + svdot_lane_za32_mf8_vg1x2_fpm(slice, f8x2, f8, 3, fpmr); + // expected-error@+1 {{'svdot_lane_za32_mf8_vg1x4_fpm' needs target feature sme,sme-f8f32}} + svdot_lane_za32_mf8_vg1x4_fpm(slice, f8x4, f8, 3, fpmr); + // expected-error@+1 {{'svdot_lane_za16_mf8_vg1x2_fpm' needs target feature sme,sme-f8f16}} + svdot_lane_za16_mf8_vg1x2_fpm(slice, f8x2, f8, 3, fpmr); + // expected-error@+1 {{'svdot_lane_za16_mf8_vg1x4_fpm' needs target feature sme,sme-f8f16}} + svdot_lane_za16_mf8_vg1x4_fpm(slice, f8x4, f8, 3, fpmr); + // expected-error@+1 {{'svdot_single_za32_mf8_vg1x2_fpm' needs target feature sme,sme-f8f32}} + svdot_single_za32_mf8_vg1x2_fpm(slice, f8x2, f8, fpmr); + // expected-error@+1 {{'svdot_single_za32_mf8_vg1x4_fpm' needs target feature sme,sme-f8f32}} + svdot_single_za32_mf8_vg1x4_fpm(slice, f8x4, f8, fpmr); + // expected-error@+1 {{'svdot_za32_mf8_vg1x2_fpm' needs target feature sme,sme-f8f32}} + svdot_za32_mf8_vg1x2_fpm(slice, f8x2, f8x2, fpmr); + // expected-error@+1 {{'svdot_za32_mf8_vg1x4_fpm' needs target feature sme,sme-f8f32}} + svdot_za32_mf8_vg1x4_fpm(slice, f8x4, f8x4, fpmr); + // expected-error@+1 {{'svdot_single_za16_mf8_vg1x2_fpm' needs target feature sme,sme-f8f16}} + svdot_single_za16_mf8_vg1x2_fpm(slice, f8x2, f8, fpmr); + // expected-error@+1 {{'svdot_single_za16_mf8_vg1x4_fpm' needs target feature sme,sme-f8f16}} + svdot_single_za16_mf8_vg1x4_fpm(slice, f8x4, f8, fpmr); + // expected-error@+1 {{'svdot_za16_mf8_vg1x2_fpm' needs target feature sme,sme-f8f16}} + svdot_za16_mf8_vg1x2_fpm(slice, f8x2, f8x2, fpmr); + // expected-error@+1 {{'svdot_za16_mf8_vg1x4_fpm' needs target feature sme,sme-f8f16}} + svdot_za16_mf8_vg1x4_fpm(slice, f8x4, f8x4, fpmr); +} + +void test_imm(uint32_t slice, svmfloat8_t f8, svmfloat8x2_t f8x2, + svmfloat8x4_t f8x4, uint64_t fpmr) __arm_streaming __arm_inout("za") { +// expected-error@+1{{argument value 18446744073709551615 is outside the valid range [0, 3]}} + svdot_lane_za32_mf8_vg1x2_fpm(slice, f8x2, f8, -1, fpmr); +// expected-error@+1{{argument value 18446744073709551615 is outside the valid range [0, 3]}} + svdot_lane_za32_mf8_vg1x4_fpm(slice, f8x4, f8, -1, fpmr); +// expected-error@+1{{argument value 18446744073709551615 is outside the valid range [0, 7]}} + svdot_lane_za16_mf8_vg1x2_fpm(slice, f8x2, f8, -1, fpmr); +// expected-error@+1{{argument value 18446744073709551615 is outside the valid range [0, 7]}} + svdot_lane_za16_mf8_vg1x4_fpm(slice, f8x4, f8, -1, fpmr); + +// expected-error@+1{{argument value 4 is outside the valid range [0, 3]}} + svdot_lane_za32_mf8_vg1x2_fpm(slice, f8x2, f8, 4, fpmr); +// expected-error@+1{{argument value 4 is outside the valid range [0, 3]}} + svdot_lane_za32_mf8_vg1x4_fpm(slice, f8x4, f8, 4, fpmr); +// expected-error@+1{{argument value 8 is outside the valid range [0, 7]}} + svdot_lane_za16_mf8_vg1x2_fpm(slice, f8x2, f8, 8, fpmr); +// expected-error@+1{{argument value 8 is outside the valid range [0, 7]}} + svdot_lane_za16_mf8_vg1x4_fpm(slice, f8x4, f8, 8, fpmr); +} diff --git a/clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_fp8_fvdot.c b/clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_fp8_fvdot.c new file mode 100644 index 0000000000000..3dc4c93457104 --- /dev/null +++ b/clang/test/Sema/aarch64-sme2-intrinsics/acle_sme2_fp8_fvdot.c @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sme -target-feature +sme2 -verify -emit-llvm -o - %s + +// REQUIRES: aarch64-registered-target + +#include + +void test_features(uint32_t slice, fpm_t fpmr, svmfloat8x2_t zn, + svmfloat8_t zm) __arm_streaming __arm_inout("za") { +// expected-error@+1 {{'svvdot_lane_za16_mf8_vg1x2_fpm' needs target feature sme,sme-f8f16}} + svvdot_lane_za16_mf8_vg1x2_fpm(slice, zn, zm, 7, fpmr); +// expected-error@+1 {{'svvdotb_lane_za32_mf8_vg1x4_fpm' needs target feature sme,sme-f8f32}} + svvdotb_lane_za32_mf8_vg1x4_fpm(slice, zn, zm, 3, fpmr); +// expected-error@+1 {{'svvdott_lane_za32_mf8_vg1x4_fpm' needs target feature sme,sme-f8f32}} + svvdott_lane_za32_mf8_vg1x4_fpm(slice, zn, zm, 3, fpmr); +} + +void test_imm(uint32_t slice, fpm_t fpmr, svmfloat8x2_t zn, + svmfloat8_t zm) __arm_streaming __arm_inout("za") { +// expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 7]}} + svvdot_lane_za16_mf8_vg1x2_fpm(slice, zn, zm, -1, fpmr); +// expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 3]}} + svvdotb_lane_za32_mf8_vg1x4_fpm(slice, zn, zm, -1, fpmr); +// expected-error@+1 {{argument value 18446744073709551615 is outside the valid range [0, 3]}} + svvdott_lane_za32_mf8_vg1x4_fpm(slice, zn, zm, -1, fpmr); + +// expected-error@+1{{argument value 8 is outside the valid range [0, 7]}} + svvdot_lane_za16_mf8_vg1x2_fpm(slice, zn, zm, 8, fpmr); +// expected-error@+1{{argument value 4 is outside the valid range [0, 3]}} + svvdotb_lane_za32_mf8_vg1x4_fpm(slice, zn, zm, 4, fpmr); +// expected-error@+1{{argument value 4 is outside the valid range [0, 3]}} + svvdott_lane_za32_mf8_vg1x4_fpm(slice, zn, zm, 4, fpmr); +} diff --git a/clang/test/Sema/aarch64-sve2-intrinsics/acle_sve2_fp8.c b/clang/test/Sema/aarch64-sve2-intrinsics/acle_sve2_fp8.c new file mode 100644 index 0000000000000..192d200eb4910 --- /dev/null +++ b/clang/test/Sema/aarch64-sve2-intrinsics/acle_sve2_fp8.c @@ -0,0 +1,103 @@ +// REQUIRES: aarch64-registered-target + +// RUN: %clang_cc1 -triple aarch64-none-linux-gnu -target-feature +sve -target-feature +bf16 -verify -emit-llvm -o - %s + +#include + +void test_features(svmfloat8_t zn, svmfloat8_t zm, mfloat8_t x, fpm_t fpm) { + svcvt1_bf16_mf8_fpm(zn, fpm); + // expected-error@-1 {{'svcvt1_bf16_mf8_fpm' needs target feature (sve,sve2,fp8)|(sme,sme2,fp8)}} + svcvt2_bf16_mf8_fpm(zn, fpm); + // expected-error@-1 {{'svcvt2_bf16_mf8_fpm' needs target feature (sve,sve2,fp8)|(sme,sme2,fp8)}} + svcvtlt1_bf16_mf8_fpm(zn, fpm); + // expected-error@-1 {{'svcvtlt1_bf16_mf8_fpm' needs target feature (sve,sve2,fp8)|(sme,sme2,fp8)}} + svcvtlt2_bf16_mf8_fpm(zn, fpm); + // expected-error@-1 {{'svcvtlt2_bf16_mf8_fpm' needs target feature (sve,sve2,fp8)|(sme,sme2,fp8)}} + svcvt1_f16_mf8_fpm(zn, fpm); + // expected-error@-1 {{'svcvt1_f16_mf8_fpm' needs target feature (sve,sve2,fp8)|(sme,sme2,fp8)}} + svcvt2_f16_mf8_fpm(zn, fpm); + // expected-error@-1 {{'svcvt2_f16_mf8_fpm' needs target feature (sve,sve2,fp8)|(sme,sme2,fp8)}} + svcvtlt1_f16_mf8_fpm(zn, fpm); + // expected-error@-1 {{'svcvtlt1_f16_mf8_fpm' needs target feature (sve,sve2,fp8)|(sme,sme2,fp8)}} + svcvtlt2_f16_mf8_fpm(zn, fpm); + // expected-error@-1 {{'svcvtlt2_f16_mf8_fpm' needs target feature (sve,sve2,fp8)|(sme,sme2,fp8)}} + + svcvtn_mf8_bf16_x2_fpm(svcreate2(svundef_bf16(), svundef_bf16()), fpm); + // expected-error@-1 {{'svcvtn_mf8_bf16_x2_fpm' needs target feature (sve,sve2,fp8)|(sme,sme2,fp8)}} + svcvtn_mf8_f16_x2_fpm(svcreate2(svundef_f16(), svundef_f16()), fpm); + // expected-error@-1 {{'svcvtn_mf8_f16_x2_fpm' needs target feature (sve,sve2,fp8)|(sme,sme2,fp8)}} + svcvtnb_mf8_f32_x2_fpm(svcreate2(svundef_f32(), svundef_f32()), fpm); + // expected-error@-1 {{'svcvtnb_mf8_f32_x2_fpm' needs target feature (sve,sve2,fp8)|(sme,sme2,fp8)}} + svcvtnt_mf8_f32_x2_fpm(zn, svcreate2(svundef_f32(), svundef_f32()), fpm); + // expected-error@-1 {{'svcvtnt_mf8_f32_x2_fpm' needs target feature (sve,sve2,fp8)|(sme,sme2,fp8)}} + + svdot_f32_mf8_fpm(svundef_f32(), zn, zm, fpm); +// expected-error@-1 {{'svdot_f32_mf8_fpm' needs target feature (sve,sve2,fp8dot4)|(sme,ssve-fp8dot4)}} + svdot_n_f32_mf8_fpm(svundef_f32(), zn, x, fpm); +// expected-error@-1 {{'svdot_n_f32_mf8_fpm' needs target feature (sve,sve2,fp8dot4)|(sme,ssve-fp8dot4)}} + svdot_f16_mf8_fpm(svundef_f16(), zn, zm, fpm); +// expected-error@-1 {{'svdot_f16_mf8_fpm' needs target feature (sve,sve2,fp8dot2)|(sme,ssve-fp8dot2)}} + svdot_n_f16_mf8_fpm(svundef_f16(), zn, x, fpm); +// expected-error@-1 {{'svdot_n_f16_mf8_fpm' needs target feature (sve,sve2,fp8dot2)|(sme,ssve-fp8dot2)}} + svdot_lane_f32_mf8_fpm(svundef_f32(), zn, zm, 3, fpm); +// expected-error@-1 {{'svdot_lane_f32_mf8_fpm' needs target feature (sve,sve2,fp8dot4)|(sme,ssve-fp8dot4)}} + svdot_lane_f16_mf8_fpm(svundef_f16(), zn, zm, 7, fpm); +// expected-error@-1 {{'svdot_lane_f16_mf8_fpm' needs target feature (sve,sve2,fp8dot2)|(sme,ssve-fp8dot2)}} + + svmlalb_f16_mf8_fpm(svundef_f16(), zn, zm, fpm); + // expected-error@-1 {{'svmlalb_f16_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlalb_n_f16_mf8_fpm(svundef_f16(), zn, x, fpm); + // expected-error@-1 {{'svmlalb_n_f16_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlalt_f16_mf8_fpm(svundef_f16(), zn, zm, fpm); + // expected-error@-1 {{'svmlalt_f16_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlalt_n_f16_mf8_fpm(svundef_f16(), zn, x, fpm); + // expected-error@-1 {{'svmlalt_n_f16_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlalb_lane_f16_mf8_fpm(svundef_f16(), zn, zm, 7, fpm); + // expected-error@-1 {{'svmlalb_lane_f16_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlalt_lane_f16_mf8_fpm(svundef_f16(), zn, zm, 7, fpm); + // expected-error@-1 {{'svmlalt_lane_f16_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlallbb_f32_mf8_fpm(svundef_f32(), zn, zm, fpm); + // expected-error@-1 {{'svmlallbb_f32_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlallbb_n_f32_mf8_fpm(svundef_f32(), zn, x, fpm); + // expected-error@-1 {{'svmlallbb_n_f32_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlallbt_f32_mf8_fpm(svundef_f32(), zn, zm, fpm); + // expected-error@-1 {{'svmlallbt_f32_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlallbt_n_f32_mf8_fpm(svundef_f32(), zn, x, fpm); + // expected-error@-1 {{'svmlallbt_n_f32_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlalltb_f32_mf8_fpm(svundef_f32(), zn, zm, fpm); + // expected-error@-1 {{'svmlalltb_f32_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlalltb_n_f32_mf8_fpm(svundef_f32(), zn, x, fpm); + // expected-error@-1 {{'svmlalltb_n_f32_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlalltt_f32_mf8_fpm(svundef_f32(), zn, zm, fpm); + // expected-error@-1 {{'svmlalltt_f32_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlalltt_n_f32_mf8_fpm(svundef_f32(), zn, x, fpm); + // expected-error@-1 {{'svmlalltt_n_f32_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlallbb_lane_f32_mf8_fpm(svundef_f32(), zn, zm, 7, fpm); + // expected-error@-1 {{'svmlallbb_lane_f32_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlallbt_lane_f32_mf8_fpm(svundef_f32(), zn, zm, 7, fpm); + // expected-error@-1 {{'svmlallbt_lane_f32_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlalltb_lane_f32_mf8_fpm(svundef_f32(), zn, zm, 7, fpm); + // expected-error@-1 {{'svmlalltb_lane_f32_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} + svmlalltt_lane_f32_mf8_fpm(svundef_f32(), zn, zm, 7, fpm); + // expected-error@-1 {{'svmlalltt_lane_f32_mf8_fpm' needs target feature (sve,sve2,fp8fma)|(sme,ssve-fp8fma)}} +} + +void test_imm_range(svmfloat8_t zn, svmfloat8_t zm, fpm_t fpm) { + svdot_lane_f32_mf8_fpm(svundef_f32(), zn, zm, -1, fpm); +// expected-error@-1 {{argument value 18446744073709551615 is outside the valid range [0, 3]}} + svdot_lane_f16_mf8_fpm(svundef_f16(), zn, zm, -1, fpm); +// expected-error@-1 {{argument value 18446744073709551615 is outside the valid range [0, 7]}} + + svmlalb_lane_f16_mf8_fpm(svundef_f16(), zn, zm, -1, fpm); + // expected-error@-1 {{argument value 18446744073709551615 is outside the valid range [0, 15]}} + svmlalt_lane_f16_mf8_fpm(svundef_f16(), zn, zm, -1, fpm); + // expected-error@-1 {{argument value 18446744073709551615 is outside the valid range [0, 15]}} + svmlallbb_lane_f32_mf8_fpm(svundef_f32(), zn, zm, -1, fpm); + // expected-error@-1 {{argument value 18446744073709551615 is outside the valid range [0, 7]}} + svmlallbt_lane_f32_mf8_fpm(svundef_f32(), zn, zm, -1, fpm); + // expected-error@-1 {{argument value 18446744073709551615 is outside the valid range [0, 7]}} + svmlalltb_lane_f32_mf8_fpm(svundef_f32(), zn, zm, -1, fpm); + // expected-error@-1 {{argument value 18446744073709551615 is outside the valid range [0, 7]}} + svmlalltt_lane_f32_mf8_fpm(svundef_f32(), zn, zm, -1, fpm); + // expected-error@-1 {{argument value 18446744073709551615 is outside the valid range [0, 7]}} +} diff --git a/clang/test/Sema/constant_builtins_vector.cpp b/clang/test/Sema/constant_builtins_vector.cpp index 45c729f76418d..b2f56e5a87ab1 100644 --- a/clang/test/Sema/constant_builtins_vector.cpp +++ b/clang/test/Sema/constant_builtins_vector.cpp @@ -822,3 +822,19 @@ static_assert(__builtin_elementwise_bitreverse(0x12345678) == 0x1E6A2C48); static_assert(__builtin_elementwise_bitreverse(0x0123456789ABCDEFULL) == 0xF7B3D591E6A2C480); static_assert(__builtin_bit_cast(unsigned, __builtin_elementwise_bitreverse((vector4char){1, 2, 4, 8})) == (LITTLE_END ? 0x10204080 : 0x80402010)); static_assert(__builtin_bit_cast(unsigned long long, __builtin_elementwise_bitreverse((vector4short){1, 2, 4, 8})) == (LITTLE_END ? 0x1000200040008000 : 0x8000400020001000)); + +static_assert(__builtin_elementwise_add_sat(1, 2) == 3); +static_assert(__builtin_elementwise_add_sat(1U, 2U) == 3U); +static_assert(__builtin_elementwise_add_sat(~(1 << 31), 42) == ~(1 << 31)); +static_assert(__builtin_elementwise_add_sat((1 << 31), -42) == (1 << 31)); +static_assert(__builtin_elementwise_add_sat(~0U, 1U) == ~0U); +static_assert(__builtin_bit_cast(unsigned, __builtin_elementwise_add_sat((vector4char){1, 2, 3, 4}, (vector4char){1, 2, 3, 4})) == (LITTLE_END ? 0x08060402 : 0x02040608)); +static_assert(__builtin_bit_cast(unsigned long long, __builtin_elementwise_add_sat((vector4short){(short)0x8000, (short)0x8001, (short)0x8002, (short)0x8003}, (vector4short){-7, -8, -9, -10}) == (LITTLE_END ? 0x8000800080008000 : 0x8000800080008000))); + +static_assert(__builtin_elementwise_sub_sat(1, 2) == -1); +static_assert(__builtin_elementwise_sub_sat(2U, 1U) == 1U); +static_assert(__builtin_elementwise_sub_sat(~(1 << 31), -42) == ~(1 << 31)); +static_assert(__builtin_elementwise_sub_sat((1 << 31), 42) == (1 << 31)); +static_assert(__builtin_elementwise_sub_sat(0U, 1U) == 0U); +static_assert(__builtin_bit_cast(unsigned, __builtin_elementwise_sub_sat((vector4char){5, 4, 3, 2}, (vector4char){1, 1, 1, 1})) == (LITTLE_END ? 0x01020304 : 0x04030201)); +static_assert(__builtin_bit_cast(unsigned long long, __builtin_elementwise_sub_sat((vector4short){(short)0x8000, (short)0x8001, (short)0x8002, (short)0x8003}, (vector4short){7, 8, 9, 10}) == (LITTLE_END ? 0x8000800080008000 : 0x8000800080008000))); diff --git a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp index fc876926ba2e6..45b4dc838f44e 100644 --- a/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/clang/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -604,8 +604,9 @@ struct [[gsl::Pointer]] Span { // Pointer from Owner std::string_view test5() { - std::string_view a = StatusOr().valueLB(); // expected-warning {{object backing the pointer will be dest}} - return StatusOr().valueLB(); // expected-warning {{returning address of local temporary}} + // The Owner doesn't own the object which its inner pointer points to. + std::string_view a = StatusOr().valueLB(); // OK + return StatusOr().valueLB(); // OK // No dangling diagnostics on non-lifetimebound methods. std::string_view b = StatusOr().valueNoLB(); @@ -652,7 +653,7 @@ Span test10(StatusOr> aa) { // Pointer> from Owner> Span test11(StatusOr> aa) { - return aa.valueLB(); // expected-warning {{address of stack memory}} + return aa.valueLB(); // OK return aa.valueNoLB(); // OK. } @@ -693,3 +694,86 @@ void test() { auto y = std::set{}.begin(); // expected-warning {{object backing the pointer}} } } // namespace GH118064 + +namespace LifetimeboundInterleave { + +const std::string& Ref(const std::string& abc [[clang::lifetimebound]]); + +std::string_view TakeSv(std::string_view abc [[clang::lifetimebound]]); +std::string_view TakeStrRef(const std::string& abc [[clang::lifetimebound]]); +std::string_view TakeStr(std::string abc [[clang::lifetimebound]]); + +std::string_view test1() { + std::string_view t1 = Ref(std::string()); // expected-warning {{object backing}} + t1 = Ref(std::string()); // expected-warning {{object backing}} + return Ref(std::string()); // expected-warning {{returning address}} + + std::string_view t2 = TakeSv(std::string()); // expected-warning {{object backing}} + t2 = TakeSv(std::string()); // expected-warning {{object backing}} + return TakeSv(std::string()); // expected-warning {{returning address}} + + std::string_view t3 = TakeStrRef(std::string()); // expected-warning {{temporary}} + t3 = TakeStrRef(std::string()); // expected-warning {{object backing}} + return TakeStrRef(std::string()); // expected-warning {{returning address}} + + + std::string_view t4 = TakeStr(std::string()); + t4 = TakeStr(std::string()); + return TakeStr(std::string()); +} + +template +struct Foo { + const T& get() const [[clang::lifetimebound]]; + const T& getNoLB() const; +}; +std::string_view test2(Foo r1, Foo r2) { + std::string_view t1 = Foo().get(); // expected-warning {{object backing}} + t1 = Foo().get(); // expected-warning {{object backing}} + return r1.get(); // expected-warning {{address of stack}} + + std::string_view t2 = Foo().get(); + t2 = Foo().get(); + return r2.get(); + + // no warning on no-LB-annotated method. + std::string_view t3 = Foo().getNoLB(); + t3 = Foo().getNoLB(); + return r1.getNoLB(); +} + +struct Bar {}; +struct [[gsl::Pointer]] Pointer { + Pointer(const Bar & bar [[clang::lifetimebound]]); +}; +Pointer test3(Bar bar) { + Pointer p = Pointer(Bar()); // expected-warning {{temporary}} + p = Pointer(Bar()); // expected-warning {{object backing}} + return bar; // expected-warning {{address of stack}} +} + +template +struct MySpan { + MySpan(const std::vector& v); + using iterator = std::iterator; + iterator begin() const [[clang::lifetimebound]]; +}; +template +typename MySpan::iterator ReturnFirstIt(const MySpan& v [[clang::lifetimebound]]); + +void test4() { + std::vector v{1}; + // MySpan doesn't own any underlying T objects, the pointee object of + // the MySpan iterator is still alive when the whole span is destroyed, thus + // no diagnostic. + const int& t1 = *MySpan(v).begin(); + const int& t2 = *ReturnFirstIt(MySpan(v)); + // Ideally, we would diagnose the following case, but due to implementation + // constraints, we do not. + const int& t4 = *MySpan(std::vector{}).begin(); + + auto it1 = MySpan(v).begin(); // expected-warning {{temporary whose address is use}} + auto it2 = ReturnFirstIt(MySpan(v)); // expected-warning {{temporary whose address is used}} +} + +} // namespace LifetimeboundInterleave diff --git a/clang/test/Sema/warn-stringcompare.c b/clang/test/Sema/warn-stringcompare.c index 78145cf42578a..44dc0a5de3a4e 100644 --- a/clang/test/Sema/warn-stringcompare.c +++ b/clang/test/Sema/warn-stringcompare.c @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -x c -fsyntax-only -verify %s // RUN: %clang_cc1 -x c++ -fsyntax-only -verify=expected,cxx %s +// RUN: %clang_cc1 -x c++ -std=c++26 -fsyntax-only -verify=expected,cxx26 %s #define DELIM "/" #define DOT "." @@ -15,15 +16,15 @@ void test(const char *d) { if (NULL == "/") return; if ("/" != DELIM) // expected-warning {{result of comparison against a string literal is unspecified (use an explicit string comparison function instead)}} - return; // cxx-warning@-1 {{comparison between two arrays}} + return; // cxx-warning@-1 {{comparison between two arrays}} cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}} if (DELIM == "/") // expected-warning {{result of comparison against a string literal is unspecified (use an explicit string comparison function instead)}} - return; // cxx-warning@-1 {{comparison between two arrays}} + return; // cxx-warning@-1 {{comparison between two arrays}} cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}} if (DELIM != NULL) return; if (NULL == DELIM) return; if (DOT != DELIM) // expected-warning {{result of comparison against a string literal is unspecified (use an explicit string comparison function instead)}} - return; // cxx-warning@-1 {{comparison between two arrays}} + return; // cxx-warning@-1 {{comparison between two arrays}} cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}} if (DELIM == DOT) // expected-warning {{result of comparison against a string literal is unspecified (use an explicit string comparison function instead)}} - return; // cxx-warning@-1 {{comparison between two arrays}} + return; // cxx-warning@-1 {{comparison between two arrays}} cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}} } diff --git a/clang/test/SemaCXX/addr-of-overloaded-function.cpp b/clang/test/SemaCXX/addr-of-overloaded-function.cpp index dd1c3462c8c1f..99f5ba613938d 100644 --- a/clang/test/SemaCXX/addr-of-overloaded-function.cpp +++ b/clang/test/SemaCXX/addr-of-overloaded-function.cpp @@ -221,20 +221,20 @@ namespace test1 { void QualifierTest() { void (Qualifiers::*X)(); - X = &Qualifiers::C; // expected-error-re {{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const': different qualifiers (unqualified vs 'const')}} - X = &Qualifiers::V; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile': different qualifiers (unqualified vs 'volatile')}} - X = &Qualifiers::R; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} __restrict': different qualifiers (unqualified vs '__restrict')}} - X = &Qualifiers::CV; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile': different qualifiers (unqualified vs 'const volatile')}} - X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const __restrict': different qualifiers (unqualified vs 'const __restrict')}} - X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile __restrict': different qualifiers (unqualified vs 'volatile __restrict')}} - X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile __restrict': different qualifiers (unqualified vs 'const volatile __restrict')}} + X = &Qualifiers::C; // expected-error-re {{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const': different qualifiers (unqualified vs 'const')}} + X = &Qualifiers::V; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile': different qualifiers (unqualified vs 'volatile')}} + X = &Qualifiers::R; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} __restrict': different qualifiers (unqualified vs '__restrict')}} + X = &Qualifiers::CV; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile': different qualifiers (unqualified vs 'const volatile')}} + X = &Qualifiers::CR; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const __restrict': different qualifiers (unqualified vs 'const __restrict')}} + X = &Qualifiers::VR; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} volatile __restrict': different qualifiers (unqualified vs 'volatile __restrict')}} + X = &Qualifiers::CVR; // expected-error-re{{assigning to 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' from incompatible type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}} const volatile __restrict': different qualifiers (unqualified vs 'const volatile __restrict')}} } struct Dummy { void N() {}; }; - void (Qualifiers::*X)() = &Dummy::N; // expected-error-re{{cannot initialize a variable of type 'void (test1::Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (test1::Dummy::*)(){{( __attribute__\(\(thiscall\)\))?}}': different classes ('test1::Qualifiers' vs 'test1::Dummy')}} + void (Qualifiers::*X)() = &Dummy::N; // expected-error-re{{cannot initialize a variable of type 'void (Qualifiers::*)(){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (test1::Dummy::*)(){{( __attribute__\(\(thiscall\)\))?}}': different classes ('Qualifiers' vs 'test1::Dummy')}} } template class PR16561 { diff --git a/clang/test/SemaCXX/calling-conv-compat.cpp b/clang/test/SemaCXX/calling-conv-compat.cpp index 2af944defd4bc..5a51e34b1478c 100644 --- a/clang/test/SemaCXX/calling-conv-compat.cpp +++ b/clang/test/SemaCXX/calling-conv-compat.cpp @@ -183,31 +183,31 @@ typedef void ( C::*memb_c_default)(); typedef void (__cdecl C::*memb_c_cdecl)(); typedef void (__thiscall C::*memb_c_thiscall)(); -// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_a_default' (aka 'void (NonVariadic::A::*)() __attribute__((thiscall))') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_a_default' (aka 'void (A::*)() __attribute__((thiscall))') for 1st argument}} void cb_memb_a_default(memb_a_default ptr); -// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (NonVariadic::A::*)() __attribute__((cdecl))') for 1st argument}} -// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (NonVariadic::A::*)() __attribute__((cdecl))') for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (A::*)() __attribute__((cdecl))') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_a_cdecl' (aka 'void (A::*)() __attribute__((cdecl))') for 1st argument}} void cb_memb_a_cdecl(memb_a_cdecl ptr); -// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_a_thiscall' (aka 'void (NonVariadic::A::*)() __attribute__((thiscall))') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_a_thiscall' (aka 'void (A::*)() __attribute__((thiscall))') for 1st argument}} void cb_memb_a_thiscall(memb_a_thiscall ptr); -// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_b_default' (aka 'void (NonVariadic::B::*)() __attribute__((thiscall))') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_b_default' (aka 'void (B::*)() __attribute__((thiscall))') for 1st argument}} void cb_memb_b_default(memb_b_default ptr); -// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (NonVariadic::B::*)() __attribute__((cdecl))') for 1st argument}} -// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (NonVariadic::B::*)() __attribute__((cdecl))') for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (B::*)() __attribute__((cdecl))') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_b_cdecl' (aka 'void (B::*)() __attribute__((cdecl))') for 1st argument}} void cb_memb_b_cdecl(memb_b_cdecl ptr); -// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_b_thiscall' (aka 'void (NonVariadic::B::*)() __attribute__((thiscall))') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_b_thiscall' (aka 'void (B::*)() __attribute__((thiscall))') for 1st argument}} void cb_memb_b_thiscall(memb_b_thiscall ptr); -// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}} -// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}} -// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_default' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_default' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}} void cb_memb_c_default(memb_c_default ptr); -// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}} -// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}} -// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (NonVariadic::C::*)() __attribute__((cdecl))') for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (C::*)() __attribute__((cdecl))') for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (C::*)() __attribute__((cdecl))') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_cdecl' (aka 'void (C::*)() __attribute__((cdecl))') for 1st argument}} void cb_memb_c_cdecl(memb_c_cdecl ptr); -// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}} -// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}} -// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (NonVariadic::C::*)() __attribute__((thiscall))') for 1st argument}} +// expected-note@+3 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((cdecl))' to 'memb_c_thiscall' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'void (NonVariadic::A::*)() __attribute__((thiscall))' to 'memb_c_thiscall' (aka 'void (C::*)() __attribute__((thiscall))') for 1st argument}} void cb_memb_c_thiscall(memb_c_thiscall ptr); void call_member() { @@ -279,11 +279,11 @@ void cb_memb_a_default(memb_a_default ptr); void cb_memb_a_cdecl(memb_a_cdecl ptr); void cb_memb_b_default(memb_b_default ptr); void cb_memb_b_cdecl(memb_b_cdecl ptr); -// expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'memb_c_default' (aka 'void (Variadic::C::*)(int, ...)') for 1st argument}} -// expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_default' (aka 'void (Variadic::C::*)(int, ...)') for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'memb_c_default' (aka 'void (C::*)(int, ...)') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_default' (aka 'void (C::*)(int, ...)') for 1st argument}} void cb_memb_c_default(memb_c_default ptr); -// expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'memb_c_cdecl' (aka 'void (Variadic::C::*)(int, ...) __attribute__((cdecl))') for 1st argument}} -// expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (Variadic::C::*)(int, ...) __attribute__((cdecl))') for 1st argument}} +// expected-note@+2 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...)' to 'memb_c_cdecl' (aka 'void (C::*)(int, ...) __attribute__((cdecl))') for 1st argument}} +// expected-note@+1 {{candidate function not viable: no known conversion from 'void (Variadic::A::*)(int, ...) __attribute__((cdecl))' to 'memb_c_cdecl' (aka 'void (C::*)(int, ...) __attribute__((cdecl))') for 1st argument}} void cb_memb_c_cdecl(memb_c_cdecl ptr); void call_member() { @@ -330,7 +330,7 @@ mptr_t __stdcall return_mptr_std(short) { void (A::*(*return_fptr_std_mptr(char))(short))(int) { return return_mptr_std; #if !_M_X64 - // expected-error@-2 {{cannot initialize return object of type 'void (MultiChunkDecls::A::*(*)(short))(int) __attribute__((thiscall))' with an lvalue of type 'mptr_t (short) __attribute__((stdcall))'}} + // expected-error@-2 {{cannot initialize return object of type 'void (A::*(*)(short))(int) __attribute__((thiscall))' with an lvalue of type 'mptr_t (short) __attribute__((stdcall))'}} #endif } diff --git a/clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp b/clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp index 03a6800898d18..8360b8fd7d8ee 100644 --- a/clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp +++ b/clang/test/SemaCXX/cxx1y-initializer-aggregates.cpp @@ -115,3 +115,14 @@ namespace nested_union { // of Test3, or we should exclude f(Test3) as a candidate. static_assert(f({1}) == 2, ""); // expected-error {{call to 'f' is ambiguous}} } + +// Fix crash issue https://github.com/llvm/llvm-project/issues/112560. +// Make sure clang compiles the following code without crashing: +namespace GH112560 { +union U { + int f = ; // expected-error {{expected expression}} +}; +void foo() { + U g{}; +} +} // namespace GH112560 diff --git a/clang/test/SemaCXX/cxx2c-pack-indexing-ext-diags.cpp b/clang/test/SemaCXX/cxx2c-pack-indexing-ext-diags.cpp index 80dfeb9b6a8bf..118af8e867f5f 100644 --- a/clang/test/SemaCXX/cxx2c-pack-indexing-ext-diags.cpp +++ b/clang/test/SemaCXX/cxx2c-pack-indexing-ext-diags.cpp @@ -19,3 +19,35 @@ void f(T... t) { // cxx11-warning@+1 {{pack indexing is a C++2c extension}} T...[0] c; } + +template +void g(T... [1]); // cxx11-warning {{'T...[1]' is no longer a pack expansion but a pack indexing type; add a name to specify a pack expansion}} \ + // cxx11-warning {{pack indexing is a C++2c extension}} \ + // cxx11-note {{candidate function template not viable}} \ + // cxx26-warning {{pack indexing is incompatible with C++ standards before C++2c}} \ + // cxx26-note {{candidate function template not viable}} + +template +void h(T... param[1]); + +template +struct S { + using type = T; +}; + +template +void h(typename T... [1]::type); // cxx11-warning {{pack indexing is a C++2c extension}} \ + // cxx26-warning {{pack indexing is incompatible with C++ standards before C++2c}} + +template +void x(T... [0]); // cxx11-warning {{'T...[0]' is no longer a pack expansion but a pack indexing type; add a name to specify a pack expansion}} \ + // cxx11-warning {{pack indexing is a C++2c extension}} \ + // cxx26-warning {{pack indexing is incompatible with C++ standards before C++2c}} + +void call() { + g(nullptr, nullptr); // cxx26-error {{no matching function for call to 'g'}} \ + // cxx11-error {{no matching function for call to 'g'}} + h(nullptr, nullptr); + h, S>("hello"); + x(nullptr); +} diff --git a/clang/test/SemaCXX/ext-int.cpp b/clang/test/SemaCXX/ext-int.cpp index 000b871ccd343..d974221e774a7 100644 --- a/clang/test/SemaCXX/ext-int.cpp +++ b/clang/test/SemaCXX/ext-int.cpp @@ -101,8 +101,10 @@ typedef _BitInt(37) __attribute__((vector_size(16))) VecTy4; // expected-error@+1{{'_BitInt' vector element width must be a power of 2}} typedef _BitInt(37) __attribute__((ext_vector_type(32))) OtherVecTy4; -// Allow _Complex: +// expected-error@+1{{'_Complex _BitInt' is invalid}} _Complex _BitInt(3) Cmplx; +// expected-error@+1{{'_Complex _BitInt' is invalid}} +typedef _Complex _BitInt(3) Cmp; // Reject cases of _Atomic: // expected-error@+1{{_Atomic cannot be applied to integer type '_BitInt(4)'}} diff --git a/clang/test/SemaCXX/matrix-type.cpp b/clang/test/SemaCXX/matrix-type.cpp index af31e267fdcae..bb7a8421ca9e3 100644 --- a/clang/test/SemaCXX/matrix-type.cpp +++ b/clang/test/SemaCXX/matrix-type.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -pedantic -fenable-matrix -std=c++11 -verify -triple x86_64-apple-darwin %s +// RUN: %clang_cc1 -fsyntax-only -fenable-matrix -std=c++11 -verify -triple x86_64-apple-darwin %s using matrix_double_t = double __attribute__((matrix_type(6, 6))); using matrix_float_t = float __attribute__((matrix_type(6, 6))); @@ -29,3 +29,13 @@ void matrix_unsupported_element_type() { using matrix3_t = bool __attribute__((matrix_type(1, 1))); // expected-error{{invalid matrix element type 'bool'}} using matrix4_t = TestEnum __attribute__((matrix_type(1, 1))); // expected-error{{invalid matrix element type 'TestEnum'}} } + +void matrix_unsupported_bit_int() { + using m1 = _BitInt(2) __attribute__((matrix_type(4, 4))); // expected-error{{'_BitInt' matrix element width must be at least as wide as 'CHAR_BIT'}} + using m2 = _BitInt(7) __attribute__((matrix_type(4, 4))); // expected-error{{'_BitInt' matrix element width must be at least as wide as 'CHAR_BIT'}} + using m3 = _BitInt(9) __attribute__((matrix_type(4, 4))); // expected-error{{'_BitInt' matrix element width must be a power of 2}} + using m4 = _BitInt(12) __attribute__((matrix_type(4, 4))); // expected-error{{'_BitInt' matrix element width must be a power of 2}} + using m5 = _BitInt(8) __attribute__((matrix_type(4, 4))); + using m6 = _BitInt(64) __attribute__((matrix_type(4, 4))); + using m7 = _BitInt(256) __attribute__((matrix_type(4, 4))); +} diff --git a/clang/test/SemaCXX/ms-constexpr-new.cpp b/clang/test/SemaCXX/ms-constexpr-new.cpp index 30567740b2ecb..096014be803e7 100644 --- a/clang/test/SemaCXX/ms-constexpr-new.cpp +++ b/clang/test/SemaCXX/ms-constexpr-new.cpp @@ -12,5 +12,12 @@ namespace std { } } -constexpr bool check_construct_at() { int x; return *std::construct_at(&x, 42) == 42; } -static_assert(check_construct_at()); +constexpr bool check_std_construct_at() { int x; return *std::construct_at(&x, 42) == 42; } +static_assert(check_std_construct_at()); + +constexpr int* construct_at(int* p, int v) { [[msvc::constexpr]] return ::new (p) int(v); } // unsupported-error {{constexpr function never produces a constant expression}} \ + // unsupported-warning {{unknown attribute 'constexpr' ignored}} \ + // unsupported-note 2{{this placement new expression is not supported in constant expressions before C++2c}} +constexpr bool check_construct_at() { int x; return *construct_at(&x, 42) == 42; } // unsupported-note {{in call to 'construct_at(&x, 42)'}} +static_assert(check_construct_at()); // unsupported-error {{static assertion expression is not an integral constant expression}}\ + // unsupported-note {{in call to 'check_construct_at()'}} diff --git a/clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp b/clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp new file mode 100644 index 0000000000000..7262ffd079a92 --- /dev/null +++ b/clang/test/SemaCXX/msvc-pragma-function-no-builtin-attr.cpp @@ -0,0 +1,32 @@ +// RUN: %clang_cl -fms-compatibility -Xclang -ast-dump -fsyntax-only -- %s | FileCheck %s + +extern "C" __inline float __cdecl fabsf( float _X); +// CHECK: FunctionDecl {{.*}} fabsf +#pragma function(fabsf) + __inline float __cdecl fabsf( float _X) +{ + return 0; +} +// CHECK: FunctionDecl {{.*}} fabsf +// CHECK: NoBuiltinAttr {{.*}} <> Implicit fabsf + +int bar() { + return 0; +} +// CHECK: FunctionDecl {{.*}} bar +// CHECK: NoBuiltinAttr {{.*}} <> Implicit fabsf + +struct A { + int foo() = delete; + // CHECK: CXXMethodDecl {{.*}} foo {{.*}} delete + // CHECK-NOT: NoBuiltinAttr + A() = default; + // CHECK: CXXConstructorDecl {{.*}} A {{.*}} default + // CHECK-NOT: NoBuiltinAttr +}; + +int main() { + return 0; +} +// CHECK: FunctionDecl {{.*}} main +// CHECK: NoBuiltinAttr {{.*}} <> Implicit fabsf diff --git a/clang/test/SemaCXX/new-delete.cpp b/clang/test/SemaCXX/new-delete.cpp index 98b168d9df1f3..fb4810ad673ad 100644 --- a/clang/test/SemaCXX/new-delete.cpp +++ b/clang/test/SemaCXX/new-delete.cpp @@ -545,6 +545,15 @@ enum GH99278_1 { zero = decltype(delete static_cast(nullptr), 0){} // expected-warning@-1 {{expression with side effects has no effect in an unevaluated context}} }; +template +struct GH99278_2 { + union b {}; + struct c { + c() { delete d; } + b *d; + } f; +}; +GH99278_2 e; #endif struct PlacementArg {}; diff --git a/clang/test/SemaCXX/noexcept-destroying-delete.cpp b/clang/test/SemaCXX/noexcept-destroying-delete.cpp new file mode 100644 index 0000000000000..92ccbc1fb3f96 --- /dev/null +++ b/clang/test/SemaCXX/noexcept-destroying-delete.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -fcxx-exceptions -Wno-unevaluated-expression -std=c++20 %s +// expected-no-diagnostics + +namespace std { + struct destroying_delete_t { + explicit destroying_delete_t() = default; + }; + + inline constexpr destroying_delete_t destroying_delete{}; +} + +struct Explicit { + ~Explicit() noexcept(false) {} + + void operator delete(Explicit*, std::destroying_delete_t) noexcept { + } +}; + +Explicit *qn = nullptr; +// This assertion used to fail, see GH118660 +static_assert(noexcept(delete(qn))); + +struct ThrowingDestroyingDelete { + ~ThrowingDestroyingDelete() noexcept(false) {} + + void operator delete(ThrowingDestroyingDelete*, std::destroying_delete_t) noexcept(false) { + } +}; + +ThrowingDestroyingDelete *pn = nullptr; +// noexcept should return false here because the destroying delete itself is a +// potentially throwing function. +static_assert(!noexcept(delete(pn))); diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp index 8b3a5d8dd3327..069a9004927a9 100644 --- a/clang/test/SemaCXX/source_location.cpp +++ b/clang/test/SemaCXX/source_location.cpp @@ -1012,3 +1012,21 @@ int h = Var; } + +namespace GH119129 { +struct X{ + constexpr int foo(std::source_location loc = std::source_location::current()) { + return loc.line(); + } +}; +static_assert(X{}.foo() == __LINE__); +static_assert(X{}. + foo() == __LINE__); +static_assert(X{}. + + + foo() == __LINE__); +#line 10000 +static_assert(X{}. + foo() == 10001); +} diff --git a/clang/test/SemaCXX/static-cast.cpp b/clang/test/SemaCXX/static-cast.cpp index 7cc4bea423d60..4b36dad64a06b 100644 --- a/clang/test/SemaCXX/static-cast.cpp +++ b/clang/test/SemaCXX/static-cast.cpp @@ -199,6 +199,6 @@ namespace PR6072 { (void)static_cast(&B::f); (void)static_cast(&B::f); (void)static_cast(&B::f); - (void)static_cast(&B::f); // expected-error-re{{address of overloaded function 'f' cannot be static_cast to type 'void (PR6072::D::*)(){{( __attribute__\(\(thiscall\)\))?}}'}} + (void)static_cast(&B::f); // expected-error-re{{address of overloaded function 'f' cannot be static_cast to type 'void (D::*)(){{( __attribute__\(\(thiscall\)\))?}}'}} } } diff --git a/clang/test/SemaCXX/warn-array-comparion.cpp b/clang/test/SemaCXX/warn-array-comparion.cpp index a6eaaab22fc16..2bd4218f3a279 100644 --- a/clang/test/SemaCXX/warn-array-comparion.cpp +++ b/clang/test/SemaCXX/warn-array-comparion.cpp @@ -1,6 +1,7 @@ // RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s -verify=expected,not-cxx20 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -Wno-deprecated-array-compare -verify %s -verify=expected,not-cxx20 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -Wdeprecated -verify %s -verify=expected,cxx20 +// RUN: %clang_cc1 -std=c++26 -fsyntax-only -Wdeprecated -verify %s -verify=expected,cxx26 typedef struct { char str[16]; @@ -9,13 +10,14 @@ typedef struct { bool object_equal(const Object &obj1, const Object &obj2) { if (obj1.str != obj2.str) // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}} - return false; + return false; // cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}} if (obj1.id != obj2.id) // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}} - return false; + return false; // cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}} return true; } void foo(int (&array1)[2], int (&array2)[2]) { if (array1 == array2) { } // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}} + // cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}} } diff --git a/clang/test/SemaCXX/warn-self-comparisons.cpp b/clang/test/SemaCXX/warn-self-comparisons.cpp index 3847c2d918bf6..1ea8b971fcd56 100644 --- a/clang/test/SemaCXX/warn-self-comparisons.cpp +++ b/clang/test/SemaCXX/warn-self-comparisons.cpp @@ -1,6 +1,8 @@ // RUN: %clang_cc1 -std=c++17 -fsyntax-only -verify %s -verify=expected,not-cxx20 // RUN: %clang_cc1 -std=c++20 -fsyntax-only -Wdeprecated -verify %s -verify=expected,cxx20 +// RUN: %clang_cc1 -std=c++26 -fsyntax-only -Wdeprecated -verify %s -verify=expected,cxx26 void f(int (&array1)[2], int (&array2)[2]) { if (array1 == array2) { } // not-cxx20-warning {{comparison between two arrays compare their addresses}} cxx20-warning {{comparison between two arrays is deprecated}} + // cxx26-error@-1 {{comparison between two arrays is ill-formed in C++26}} } diff --git a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp index 8477200456d98..3c52c8165d852 100644 --- a/clang/test/SemaCXX/warn-thread-safety-analysis.cpp +++ b/clang/test/SemaCXX/warn-thread-safety-analysis.cpp @@ -1593,8 +1593,12 @@ namespace substitution_test { void unlockData() UNLOCK_FUNCTION(mu); void doSomething() EXCLUSIVE_LOCKS_REQUIRED(mu) { } + void operator()() EXCLUSIVE_LOCKS_REQUIRED(mu) { } + + MyData operator+(const MyData& other) const SHARED_LOCKS_REQUIRED(mu, other.mu); }; + MyData operator-(const MyData& a, const MyData& b) SHARED_LOCKS_REQUIRED(a.mu, b.mu); class DataLocker { public: @@ -1607,6 +1611,27 @@ namespace substitution_test { public: void foo(MyData* d) EXCLUSIVE_LOCKS_REQUIRED(d->mu) { } + void subst(MyData& d) { + d.doSomething(); // expected-warning {{calling function 'doSomething' requires holding mutex 'd.mu' exclusively}} + d(); // expected-warning {{calling function 'operator()' requires holding mutex 'd.mu' exclusively}} + d.operator()(); // expected-warning {{calling function 'operator()' requires holding mutex 'd.mu' exclusively}} + + d.lockData(); + d.doSomething(); + d(); + d.operator()(); + d.unlockData(); + } + + void binop(MyData& a, MyData& b) EXCLUSIVE_LOCKS_REQUIRED(a.mu) { + a + b; // expected-warning {{calling function 'operator+' requires holding mutex 'b.mu'}} + // expected-note@-1 {{found near match 'a.mu'}} + b + a; // expected-warning {{calling function 'operator+' requires holding mutex 'b.mu'}} + // expected-note@-1 {{found near match 'a.mu'}} + a - b; // expected-warning {{calling function 'operator-' requires holding mutex 'b.mu'}} + // expected-note@-1 {{found near match 'a.mu'}} + } + void bar1(MyData* d) { d->lockData(); foo(d); @@ -5172,9 +5197,13 @@ class Foo { }; func1(); // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}} + func1.operator()(); // expected-warning {{calling function 'operator()' requires holding mutex 'mu_' exclusively}} func2(); + func2.operator()(); func3(); mu_.Unlock(); + func3.operator()(); + mu_.Unlock(); } }; diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp index c6c93a27e4b96..7dd6c83dbba2a 100644 --- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp @@ -52,3 +52,43 @@ void constant_id_string(unsigned idx) { unsafe_char = ""[1]; //expected-warning{{unsafe buffer access}} unsafe_char = ""[idx]; //expected-warning{{unsafe buffer access}} } + +typedef float Float4x4[4][4]; + +// expected-warning@+1 {{'matrix' is an unsafe buffer that does not perform bounds checks}} +float two_dimension_array(Float4x4& matrix, unsigned idx) { + // expected-warning@+1{{unsafe buffer access}} + float a = matrix[0][4]; + + a = matrix[0][3]; + + // expected-note@+1{{used in buffer access here}} + a = matrix[4][0]; + + a = matrix[idx][0]; // expected-note{{used in buffer access here}} + + a = matrix[0][idx]; //expected-warning{{unsafe buffer access}} + + a = matrix[idx][idx]; //expected-warning{{unsafe buffer access}} // expected-note{{used in buffer access here}} + + return matrix[1][1]; +} + +typedef float Float2x3x4[2][3][4]; +float multi_dimension_array(Float2x3x4& matrix) { + float *f = matrix[0][2]; + return matrix[1][2][3]; +} + +char array_strings[][11] = { + "Apple", "Banana", "Cherry", "Date", "Elderberry" +}; + +char array_string[] = "123456"; + +char access_strings() { + char c = array_strings[0][4]; + c = array_strings[3][10]; + c = array_string[5]; + return c; +} diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-field-attr.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-field-attr.cpp index 0ba605475925b..1636c948da075 100644 --- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-field-attr.cpp +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-field-attr.cpp @@ -96,7 +96,6 @@ void test_attribute_multiple_fields (D d) { int v = d.buf[0]; //expected-warning{{field 'buf' prone to unsafe buffer manipulation}} - //expected-warning@+1{{unsafe buffer access}} v = d.buf[5]; //expected-warning{{field 'buf' prone to unsafe buffer manipulation}} } diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp index 71350098613d1..0c80da63f8291 100644 --- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp @@ -118,7 +118,7 @@ void isArrayDecayToPointerUPC(int a[][10], int (*b)[10]) { // expected-warning@-2{{'b' is an unsafe pointer used for buffer access}} int tmp; - tmp = a[5][5] + b[5][5]; // expected-warning2{{unsafe buffer access}} expected-note2{{used in buffer access here}} + tmp = a[5][5] + b[5][5]; // expected-note2{{used in buffer access here}} } // parameter having default values: diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp index 642db0e9d3c63..41d38ada48788 100644 --- a/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp @@ -109,7 +109,6 @@ void testQualifiedParameters(const int * p, const int * const q, const int a[10] q[1], 1[q], q[-1], // expected-note3{{used in buffer access here}} a[1], // expected-note{{used in buffer access here}} `a` is of pointer type b[1][2] // expected-note{{used in buffer access here}} `b[1]` is of array type - // expected-warning@-1{{unsafe buffer access}} ); } @@ -128,29 +127,41 @@ T_t funRetT(); T_t * funRetTStar(); void testStructMembers(struct T * sp, struct T s, T_t * sp2, T_t s2) { - foo(sp->a[1], // expected-warning{{unsafe buffer access}} + foo(sp->a[1], sp->b[1], // expected-warning{{unsafe buffer access}} - sp->c.a[1], // expected-warning{{unsafe buffer access}} + sp->c.a[1], sp->c.b[1], // expected-warning{{unsafe buffer access}} - s.a[1], // expected-warning{{unsafe buffer access}} + s.a[1], s.b[1], // expected-warning{{unsafe buffer access}} - s.c.a[1], // expected-warning{{unsafe buffer access}} + s.c.a[1], s.c.b[1], // expected-warning{{unsafe buffer access}} - sp2->a[1], // expected-warning{{unsafe buffer access}} + sp2->a[1], sp2->b[1], // expected-warning{{unsafe buffer access}} - sp2->c.a[1], // expected-warning{{unsafe buffer access}} + sp2->c.a[1], sp2->c.b[1], // expected-warning{{unsafe buffer access}} - s2.a[1], // expected-warning{{unsafe buffer access}} + s2.a[1], s2.b[1], // expected-warning{{unsafe buffer access}} - s2.c.a[1], // expected-warning{{unsafe buffer access}} + s2.c.a[1], s2.c.b[1], // expected-warning{{unsafe buffer access}} - funRetT().a[1], // expected-warning{{unsafe buffer access}} + funRetT().a[1], funRetT().b[1], // expected-warning{{unsafe buffer access}} - funRetTStar()->a[1], // expected-warning{{unsafe buffer access}} + funRetTStar()->a[1], funRetTStar()->b[1] // expected-warning{{unsafe buffer access}} ); } +union Foo { + bool b; + int arr[10]; +}; + +int testUnionMembers(Foo f) { + int a = f.arr[0]; + a = f.arr[5]; + a = f.arr[10]; // expected-warning{{unsafe buffer access}} + return a; +} + int garray[10]; // expected-warning{{'garray' is an unsafe buffer that does not perform bounds checks}} int * gp = garray; // expected-warning{{'gp' is an unsafe pointer used for buffer access}} int gvar = gp[1]; // FIXME: file scope unsafe buffer access is not warned @@ -213,7 +224,6 @@ void testTypedefs(T_ptr_t p) { // expected-warning@-1{{'p' is an unsafe pointer used for buffer access}} foo(p[1], // expected-note{{used in buffer access here}} p[1].a[1], // expected-note{{used in buffer access here}} - // expected-warning@-1{{unsafe buffer access}} p[1].b[1] // expected-note{{used in buffer access here}} // expected-warning@-1{{unsafe buffer access}} ); @@ -223,10 +233,9 @@ template T f(T t, T * pt, T a[N], T (&b)[N]) { // expected-warning@-1{{'t' is an unsafe pointer used for buffer access}} // expected-warning@-2{{'pt' is an unsafe pointer used for buffer access}} // expected-warning@-3{{'a' is an unsafe pointer used for buffer access}} - // expected-warning@-4{{'b' is an unsafe buffer that does not perform bounds checks}} foo(pt[1], // expected-note{{used in buffer access here}} a[1], // expected-note{{used in buffer access here}} - b[1]); // expected-note{{used in buffer access here}} + b[1]); return &t[1]; // expected-note{{used in buffer access here}} } @@ -376,7 +385,7 @@ int testArrayAccesses(int n, int idx) { typedef int A[3]; const A tArr = {4, 5, 6}; foo(tArr[0], tArr[1]); - return cArr[0][1]; // expected-warning{{unsafe buffer access}} + return cArr[0][1]; } void testArrayPtrArithmetic(int x[]) { // expected-warning{{'x' is an unsafe pointer used for buffer access}} diff --git a/clang/test/SemaCXX/warn-unused-private-field.cpp b/clang/test/SemaCXX/warn-unused-private-field.cpp index bf104b1a76a65..0cc6f687f1b35 100644 --- a/clang/test/SemaCXX/warn-unused-private-field.cpp +++ b/clang/test/SemaCXX/warn-unused-private-field.cpp @@ -40,6 +40,20 @@ class FriendEqDefaultCompareOutOfClass { bool operator==(const FriendEqDefaultCompareOutOfClass &, const FriendEqDefaultCompareOutOfClass &) = default; +class HasUnusedField { + int unused_; // expected-warning{{private field 'unused_' is not used}} +}; + +class FriendEqDefaultCompare { + int used; + friend auto operator==(FriendEqDefaultCompare, FriendEqDefaultCompare) -> bool = default; +}; + +class UnrelatedFriendEqDefaultCompare { + friend auto operator==(UnrelatedFriendEqDefaultCompare, UnrelatedFriendEqDefaultCompare) -> bool = default; + int operator<=>(const UnrelatedFriendEqDefaultCompare &) const = default; +}; + #endif class NotFullyDefined { diff --git a/clang/test/SemaHLSL/BuiltIns/WaveActiveAllTrue-errors.hlsl b/clang/test/SemaHLSL/BuiltIns/WaveActiveAllTrue-errors.hlsl new file mode 100644 index 0000000000000..b0d0fdfca5e18 --- /dev/null +++ b/clang/test/SemaHLSL/BuiltIns/WaveActiveAllTrue-errors.hlsl @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -finclude-default-header -triple dxil-pc-shadermodel6.6-library %s -emit-llvm-only -disable-llvm-passes -verify + +bool test_too_few_arg() { + return __builtin_hlsl_wave_active_all_true(); + // expected-error@-1 {{too few arguments to function call, expected 1, have 0}} +} + +bool test_too_many_arg(bool p0) { + return __builtin_hlsl_wave_active_all_true(p0, p0); + // expected-error@-1 {{too many arguments to function call, expected 1, have 2}} +} + +struct Foo +{ + int a; +}; + +bool test_type_check(Foo p0) { + return __builtin_hlsl_wave_active_all_true(p0); + // expected-error@-1 {{no viable conversion from 'Foo' to 'bool'}} +} diff --git a/clang/test/SemaHLSL/Semantics/entry_parameter.hlsl b/clang/test/SemaHLSL/Semantics/entry_parameter.hlsl index 13c07038d2e4a..393d7300605c0 100644 --- a/clang/test/SemaHLSL/Semantics/entry_parameter.hlsl +++ b/clang/test/SemaHLSL/Semantics/entry_parameter.hlsl @@ -1,16 +1,14 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -hlsl-entry CSMain -x hlsl -finclude-default-header -ast-dump -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-mesh -hlsl-entry CSMain -x hlsl -finclude-default-header -verify -o - %s [numthreads(8,8,1)] -// expected-error@+3 {{attribute 'SV_GroupIndex' is unsupported in 'mesh' shaders, requires compute}} -// expected-error@+2 {{attribute 'SV_DispatchThreadID' is unsupported in 'mesh' shaders, requires compute}} -// expected-error@+1 {{attribute 'SV_GroupID' is unsupported in 'mesh' shaders, requires compute}} -void CSMain(int GI : SV_GroupIndex, uint ID : SV_DispatchThreadID, uint GID : SV_GroupID) { -// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain 'void (int, uint, uint)' +void CSMain(int GI : SV_GroupIndex, uint ID : SV_DispatchThreadID, uint GID : SV_GroupID, uint GThreadID : SV_GroupThreadID) { +// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain 'void (int, uint, uint, uint)' // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:17 GI 'int' // CHECK-NEXT: HLSLSV_GroupIndexAttr // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:42 ID 'uint' // CHECK-NEXT: HLSLSV_DispatchThreadIDAttr // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:73 GID 'uint' // CHECK-NEXT: HLSLSV_GroupIDAttr +// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:96 GThreadID 'uint' +// CHECK-NEXT: HLSLSV_GroupThreadIDAttr } diff --git a/clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl b/clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl index 4e1f88aa2294b..1bb4ee5182d62 100644 --- a/clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl +++ b/clang/test/SemaHLSL/Semantics/invalid_entry_parameter.hlsl @@ -49,3 +49,33 @@ struct ST2_GID { static uint GID : SV_GroupID; uint s_gid : SV_GroupID; }; + +[numthreads(8,8,1)] +// expected-error@+1 {{attribute 'SV_GroupThreadID' only applies to a field or parameter of type 'uint/uint2/uint3'}} +void CSMain_GThreadID(float ID : SV_GroupThreadID) { +} + +[numthreads(8,8,1)] +// expected-error@+1 {{attribute 'SV_GroupThreadID' only applies to a field or parameter of type 'uint/uint2/uint3'}} +void CSMain2_GThreadID(ST GID : SV_GroupThreadID) { + +} + +void foo_GThreadID() { +// expected-warning@+1 {{'SV_GroupThreadID' attribute only applies to parameters and non-static data members}} + uint GThreadIS : SV_GroupThreadID; +} + +struct ST2_GThreadID { +// expected-warning@+1 {{'SV_GroupThreadID' attribute only applies to parameters and non-static data members}} + static uint GThreadID : SV_GroupThreadID; + uint s_gthreadid : SV_GroupThreadID; +}; + + +[shader("vertex")] +// expected-error@+4 {{attribute 'SV_GroupIndex' is unsupported in 'vertex' shaders, requires compute}} +// expected-error@+3 {{attribute 'SV_DispatchThreadID' is unsupported in 'vertex' shaders, requires compute}} +// expected-error@+2 {{attribute 'SV_GroupID' is unsupported in 'vertex' shaders, requires compute}} +// expected-error@+1 {{attribute 'SV_GroupThreadID' is unsupported in 'vertex' shaders, requires compute}} +void vs_main(int GI : SV_GroupIndex, uint ID : SV_DispatchThreadID, uint GID : SV_GroupID, uint GThreadID : SV_GroupThreadID) {} diff --git a/clang/test/SemaHLSL/Semantics/valid_entry_parameter.hlsl b/clang/test/SemaHLSL/Semantics/valid_entry_parameter.hlsl index 10a5e5dabac87..6781f9241df24 100644 --- a/clang/test/SemaHLSL/Semantics/valid_entry_parameter.hlsl +++ b/clang/test/SemaHLSL/Semantics/valid_entry_parameter.hlsl @@ -49,3 +49,28 @@ void CSMain3_GID(uint3 : SV_GroupID) { // CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:24 'uint3' // CHECK-NEXT: HLSLSV_GroupIDAttr } + +[numthreads(8,8,1)] +void CSMain_GThreadID(uint ID : SV_GroupThreadID) { +// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain_GThreadID 'void (uint)' +// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:28 ID 'uint' +// CHECK-NEXT: HLSLSV_GroupThreadIDAttr +} +[numthreads(8,8,1)] +void CSMain1_GThreadID(uint2 ID : SV_GroupThreadID) { +// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain1_GThreadID 'void (uint2)' +// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:30 ID 'uint2' +// CHECK-NEXT: HLSLSV_GroupThreadIDAttr +} +[numthreads(8,8,1)] +void CSMain2_GThreadID(uint3 ID : SV_GroupThreadID) { +// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain2_GThreadID 'void (uint3)' +// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:30 ID 'uint3' +// CHECK-NEXT: HLSLSV_GroupThreadIDAttr +} +[numthreads(8,8,1)] +void CSMain3_GThreadID(uint3 : SV_GroupThreadID) { +// CHECK: FunctionDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> line:[[@LINE-1]]:6 CSMain3_GThreadID 'void (uint3)' +// CHECK-NEXT: ParmVarDecl 0x{{[0-9a-fA-F]+}} <{{.*}}> col:30 'uint3' +// CHECK-NEXT: HLSLSV_GroupThreadIDAttr +} diff --git a/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c b/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c index a6f57a63a91dd..a71d25ce61bed 100644 --- a/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c +++ b/clang/test/SemaOpenACC/combined-construct-auto_seq_independent-clauses.c @@ -1,8 +1,5 @@ // RUN: %clang_cc1 %s -fopenacc -verify -// TODO: OpenACC: A number of the 'not yet implemented' diagnostics interfere -// with the diagnostics we want to make here, so as we implement these, we need -// to replace the errors we should have. void uses() { #pragma acc parallel loop auto for(unsigned i = 0; i < 5; ++i); @@ -40,16 +37,14 @@ void uses() { int *VarPtr; // 'auto' can combine with any other clause. - // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop auto finalize for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop auto if_present for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'worker' not yet implemented}} #pragma acc parallel loop auto worker for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'vector' not yet implemented}} #pragma acc parallel loop auto vector for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} @@ -69,15 +64,15 @@ void uses() { // expected-warning@+1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}} #pragma acc parallel loop auto present_or_copy(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop auto use_device(Var) for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop auto attach(VarPtr) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop auto delete(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop auto detach(Var) for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} @@ -126,7 +121,6 @@ void uses() { // expected-warning@+1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}} #pragma acc parallel loop auto present_or_create(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}} #pragma acc parallel loop auto reduction(+:Var) for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop auto collapse(1) @@ -155,22 +149,19 @@ void uses() { #pragma acc parallel loop auto tile(1+2, 1) for(unsigned j = 0; j < 5; ++j) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'gang' not yet implemented}} #pragma acc parallel loop auto gang for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop auto wait for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop finalize auto for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop if_present auto for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'worker' not yet implemented}} #pragma acc parallel loop worker auto for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'vector' not yet implemented}} #pragma acc parallel loop vector auto for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} @@ -190,15 +181,15 @@ void uses() { // expected-warning@+1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}} #pragma acc parallel loop present_or_copy(Var) auto for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop use_device(Var) auto for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop attach(VarPtr) auto for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop delete(Var) auto for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop detach(Var) auto for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} @@ -247,7 +238,6 @@ void uses() { // expected-warning@+1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}} #pragma acc parallel loop present_or_create(Var) auto for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}} #pragma acc parallel loop reduction(+:Var) auto for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop collapse(1) auto @@ -276,23 +266,20 @@ void uses() { #pragma acc parallel loop tile(1+2, 1) auto for(unsigned j = 0; j < 5; ++j) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'gang' not yet implemented}} #pragma acc parallel loop gang auto for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop wait auto for(unsigned i = 0; i < 5; ++i); // 'independent' can also be combined with any clauses - // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop independent finalize for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop independent if_present for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'worker' not yet implemented}} #pragma acc parallel loop independent worker for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'vector' not yet implemented}} #pragma acc parallel loop independent vector for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} @@ -312,15 +299,15 @@ void uses() { // expected-warning@+1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}} #pragma acc parallel loop independent present_or_copy(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop independent use_device(Var) for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop independent attach(VarPtr) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop independent delete(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop independent detach(Var) for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} @@ -369,7 +356,6 @@ void uses() { // expected-warning@+1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}} #pragma acc parallel loop independent present_or_create(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}} #pragma acc parallel loop independent reduction(+:Var) for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop independent collapse(1) @@ -398,22 +384,19 @@ void uses() { #pragma acc parallel loop independent tile(1+2, 1) for(unsigned j = 0; j < 5; ++j) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'gang' not yet implemented}} #pragma acc parallel loop independent gang for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop independent wait for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop finalize independent for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop if_present independent for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'worker' not yet implemented}} #pragma acc parallel loop worker independent for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'vector' not yet implemented}} #pragma acc parallel loop vector independent for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} @@ -433,15 +416,15 @@ void uses() { // expected-warning@+1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}} #pragma acc parallel loop present_or_copy(Var) independent for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop use_device(Var) independent for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop attach(VarPtr) independent for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop delete(Var) independent for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop detach(Var) independent for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} @@ -490,7 +473,6 @@ void uses() { // expected-warning@+1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}} #pragma acc parallel loop present_or_create(Var) independent for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}} #pragma acc parallel loop reduction(+:Var) independent for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop collapse(1) independent @@ -519,7 +501,6 @@ void uses() { #pragma acc parallel loop tile(1+2, 1) independent for(unsigned j = 0; j < 5; ++j) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'gang' not yet implemented}} #pragma acc parallel loop gang independent for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop wait independent @@ -538,10 +519,10 @@ void uses() { // expected-note@+1{{previous clause is here}} #pragma acc parallel loop seq vector for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop seq finalize for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop seq if_present for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} @@ -561,15 +542,15 @@ void uses() { // expected-warning@+1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}} #pragma acc parallel loop seq present_or_copy(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop seq use_device(Var) for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop seq attach(VarPtr) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop seq delete(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop seq detach(Var) for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} @@ -618,7 +599,6 @@ void uses() { // expected-warning@+1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}} #pragma acc parallel loop seq present_or_create(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}} #pragma acc parallel loop seq reduction(+:Var) for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop seq collapse(1) @@ -650,25 +630,22 @@ void uses() { #pragma acc parallel loop seq wait for(unsigned i = 0; i < 5; ++i); - // TODOexpected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'gang' clause on a 'parallel loop' construct}} - // TODOexpected-note@+1{{previous clause is here}} - // expected-warning@+1{{OpenACC clause 'gang' not yet implemented}} + // expected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'gang' clause on a 'parallel loop' construct}} + // expected-note@+1{{previous clause is here}} #pragma acc parallel loop gang seq for(unsigned i = 0; i < 5; ++i); - // TODOexpected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'worker' clause on a 'parallel loop' construct}} - // TODOexpected-note@+1{{previous clause is here}} - // expected-warning@+1{{OpenACC clause 'worker' not yet implemented}} + // expected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'worker' clause on a 'parallel loop' construct}} + // expected-note@+1{{previous clause is here}} #pragma acc parallel loop worker seq for(unsigned i = 0; i < 5; ++i); - // TODOexpected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'vector' clause on a 'parallel loop' construct}} - // TODOexpected-note@+1{{previous clause is here}} - // expected-warning@+1{{OpenACC clause 'vector' not yet implemented}} + // expected-error@+2{{OpenACC clause 'seq' may not appear on the same construct as a 'vector' clause on a 'parallel loop' construct}} + // expected-note@+1{{previous clause is here}} #pragma acc parallel loop vector seq for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop finalize seq for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop if_present seq for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} @@ -688,15 +665,15 @@ void uses() { // expected-warning@+1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}} #pragma acc parallel loop present_or_copy(Var) seq for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop use_device(Var) seq for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop attach(VarPtr) seq for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop delete(Var) seq for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'parallel loop' directive}} #pragma acc parallel loop detach(Var) seq for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} @@ -745,7 +722,6 @@ void uses() { // expected-warning@+1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}} #pragma acc parallel loop present_or_create(Var) seq for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'reduction' not yet implemented}} #pragma acc parallel loop reduction(+:Var) seq for(unsigned i = 0; i < 5; ++i); #pragma acc parallel loop collapse(1) seq diff --git a/clang/test/SemaOpenACC/combined-construct-collapse-clause.cpp b/clang/test/SemaOpenACC/combined-construct-collapse-clause.cpp index c7db9669a9879..f2be6622007c3 100644 --- a/clang/test/SemaOpenACC/combined-construct-collapse-clause.cpp +++ b/clang/test/SemaOpenACC/combined-construct-collapse-clause.cpp @@ -214,14 +214,17 @@ void no_other_directives() { #pragma acc serial loop collapse(2) for(unsigned i = 0; i < 5; ++i) { for(unsigned j = 0; j < 5; ++j) { -#pragma acc data // expected-warning{{OpenACC construct 'data' not yet implemented}} + // expected-error@+1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} +#pragma acc data + ; } } // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc kernels loop collapse(2) for(unsigned i = 0; i < 5; ++i) { + // expected-error@+2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} // expected-error@+1{{OpenACC 'data' construct cannot appear in intervening code of a 'kernels loop' with a 'collapse' clause}} -#pragma acc data // expected-warning{{OpenACC construct 'data' not yet implemented}} +#pragma acc data for(unsigned j = 0; j < 5; ++j) { } } diff --git a/clang/test/SemaOpenACC/combined-construct-default-ast.cpp b/clang/test/SemaOpenACC/combined-construct-default-ast.cpp index 2ff24b32afe7b..8f09e74907318 100644 --- a/clang/test/SemaOpenACC/combined-construct-default-ast.cpp +++ b/clang/test/SemaOpenACC/combined-construct-default-ast.cpp @@ -1,4 +1,3 @@ - // RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s // Test this with PCH. diff --git a/clang/test/SemaOpenACC/combined-construct-default-clause.c b/clang/test/SemaOpenACC/combined-construct-default-clause.c index a9c90240cb122..43c2883f13184 100644 --- a/clang/test/SemaOpenACC/combined-construct-default-clause.c +++ b/clang/test/SemaOpenACC/combined-construct-default-clause.c @@ -28,8 +28,6 @@ void SingleOnly() { #pragma acc kernels loop default(none) for(int i = 0; i < 5; ++i); - // expected-warning@+2{{OpenACC construct 'data' not yet implemented}} - // expected-warning@+1{{OpenACC clause 'default' not yet implemented}} #pragma acc data default(none) while(0); diff --git a/clang/test/SemaOpenACC/combined-construct-device_type-clause.c b/clang/test/SemaOpenACC/combined-construct-device_type-clause.c index 9a60fb4c665e5..40339941f51a9 100644 --- a/clang/test/SemaOpenACC/combined-construct-device_type-clause.c +++ b/clang/test/SemaOpenACC/combined-construct-device_type-clause.c @@ -39,16 +39,13 @@ void uses() { // 'worker', 'vector', 'seq', 'independent', 'auto', and 'tile' after // 'device_type'. - //expected-warning@+1{{OpenACC clause 'vector' not yet implemented, clause ignored}} #pragma acc parallel loop device_type(*) vector for(int i = 0; i < 5; ++i); - // expected-error@+2{{OpenACC clause 'finalize' may not follow a 'device_type' clause in a 'serial loop' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'serial loop' directive}} #pragma acc serial loop device_type(*) finalize for(int i = 0; i < 5; ++i); - // expected-error@+2{{OpenACC clause 'if_present' may not follow a 'device_type' clause in a 'kernels loop' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'kernels loop' directive}} #pragma acc kernels loop device_type(*) if_present for(int i = 0; i < 5; ++i); #pragma acc parallel loop device_type(*) seq @@ -57,7 +54,6 @@ void uses() { for(int i = 0; i < 5; ++i); #pragma acc kernels loop device_type(*) auto for(int i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'worker' not yet implemented, clause ignored}} #pragma acc parallel loop device_type(*) worker for(int i = 0; i < 5; ++i); // expected-error@+2{{OpenACC clause 'nohost' may not follow a 'device_type' clause in a 'serial loop' construct}} @@ -91,20 +87,17 @@ void uses() { // expected-note@+1{{previous clause is here}} #pragma acc serial loop device_type(*) present_or_copy(Var) for(int i = 0; i < 5; ++i); - // expected-error@+2{{OpenACC clause 'use_device' may not follow a 'device_type' clause in a 'kernels loop' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'kernels loop' directive}} #pragma acc kernels loop device_type(*) use_device(Var) for(int i = 0; i < 5; ++i); // expected-error@+2{{OpenACC clause 'attach' may not follow a 'device_type' clause in a 'parallel loop' construct}} // expected-note@+1{{previous clause is here}} #pragma acc parallel loop device_type(*) attach(Var) for(int i = 0; i < 5; ++i); - // expected-error@+2{{OpenACC clause 'delete' may not follow a 'device_type' clause in a 'serial loop' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'serial loop' directive}} #pragma acc serial loop device_type(*) delete(Var) for(int i = 0; i < 5; ++i); - // expected-error@+2{{OpenACC clause 'detach' may not follow a 'device_type' clause in a 'kernels loop' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'kernels loop' directive}} #pragma acc kernels loop device_type(*) detach(Var) for(int i = 0; i < 5; ++i); // expected-error@+2{{OpenACC clause 'device' may not follow a 'device_type' clause in a 'parallel loop' construct}} @@ -212,7 +205,6 @@ void uses() { for(int j = 0; j < 5; ++j) for(int i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'gang' not yet implemented, clause ignored}} #pragma acc serial loop dtype(*) gang for(int i = 0; i < 5; ++i); #pragma acc parallel loop device_type(*) wait diff --git a/clang/test/SemaOpenACC/combined-construct-gang-ast.cpp b/clang/test/SemaOpenACC/combined-construct-gang-ast.cpp new file mode 100644 index 0000000000000..167f56289c58d --- /dev/null +++ b/clang/test/SemaOpenACC/combined-construct-gang-ast.cpp @@ -0,0 +1,215 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s +#ifndef PCH_HELPER +#define PCH_HELPER +void NormalUses() { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK-NEXT: CompoundStmt + + int Val; + +#pragma acc parallel loop gang(dim:1) + for(int i = 0; i < 5; ++i); + // CHECK: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause dim + // CHECK-NEXT: ConstantExpr + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc parallel loop gang(static:Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause static + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc kernels loop gang(num:1) gang(static:Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: gang clause num + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 + // CHECK-NEXT: gang clause static + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc parallel loop gang(dim:1, static:Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause dim static + // CHECK-NEXT: ConstantExpr + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc serial loop gang(static:Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop + // CHECK-NEXT: gang clause static + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc serial loop gang(static:*) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop + // CHECK-NEXT: gang clause static + // CHECK-NEXT: OpenACCAsteriskSizeExpr + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc serial loop gang + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop + // CHECK-NEXT: gang clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc kernels loop gang(num:1) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: gang clause num + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 1 + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +} + +template +void TemplateUses(T Val) { + // CHECK: FunctionTemplateDecl{{.*}}TemplateUses + // CHECK-NEXT: TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'unsigned int' depth 0 index 1 One + // CHECK-NEXT: FunctionDecl{{.*}} TemplateUses 'void (T)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced Val 'T' + // CHECK-NEXT: CompoundStmt + +#pragma acc parallel loop gang(dim:One) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause dim + // CHECK-NEXT: DeclRefExpr{{.*}}'One' 'unsigned int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc parallel loop gang(static:Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause static + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'T' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + +#pragma acc parallel loop gang(static:*) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause static + // CHECK-NEXT: OpenACCAsteriskSizeExpr + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc parallel loop gang(dim:One) gang(static:Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause dim + // CHECK-NEXT: DeclRefExpr{{.*}}'One' 'unsigned int' + // CHECK-NEXT: gang clause static + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'T' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc parallel loop gang(dim:One, static:Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause dim static + // CHECK-NEXT: DeclRefExpr{{.*}}'One' 'unsigned int' + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'T' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc serial loop gang + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop + // CHECK-NEXT: gang clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // Instantiation: + // CHECK-NEXT: FunctionDecl{{.*}} used TemplateUses 'void (int)' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: TemplateArgument integral '1U' + // CHECK-NEXT: ParmVarDecl{{.*}} used Val 'int' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause dim + // CHECK-NEXT: ConstantExpr + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: SubstNonTypeTemplateParmExpr + // CHECK-NEXT: NonTypeTemplateParmDecl + // CHECK-NEXT: IntegerLiteral{{.*}}'unsigned int' 1 + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause static + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause static + // CHECK-NEXT: OpenACCAsteriskSizeExpr + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause dim + // CHECK-NEXT: ConstantExpr + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: SubstNonTypeTemplateParmExpr + // CHECK-NEXT: NonTypeTemplateParmDecl + // CHECK-NEXT: IntegerLiteral{{.*}}'unsigned int' 1 + // CHECK-NEXT: gang clause static + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: gang clause dim static + // CHECK-NEXT: ConstantExpr + // CHECK-NEXT: value: Int 1 + // CHECK-NEXT: SubstNonTypeTemplateParmExpr + // CHECK-NEXT: NonTypeTemplateParmDecl + // CHECK-NEXT: IntegerLiteral{{.*}}'unsigned int' 1 + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop + // CHECK-NEXT: gang clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +} + +void inst() { + TemplateUses(5); +} + +#endif // PCH_HELPER diff --git a/clang/test/SemaOpenACC/combined-construct-gang-clause.cpp b/clang/test/SemaOpenACC/combined-construct-gang-clause.cpp new file mode 100644 index 0000000000000..c5346c4cf5b90 --- /dev/null +++ b/clang/test/SemaOpenACC/combined-construct-gang-clause.cpp @@ -0,0 +1,307 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +struct S{}; +struct Converts{ + operator int(); +}; + +template +void ParallelTempl() { + T i; + + // expected-error@+1{{'num' argument on 'gang' clause is not permitted on a 'parallel loop' construct}} +#pragma acc parallel loop gang(i) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'num' argument on 'gang' clause is not permitted on a 'parallel loop' construct}} +#pragma acc parallel loop gang(num:i) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{argument to 'gang' clause dimension must be a constant expression}} +#pragma acc parallel loop gang(dim:i) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 0}} +#pragma acc parallel loop gang(dim:Zero) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop gang(dim:Two) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 4}} +#pragma acc parallel loop gang(dim:Four) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop gang(static:i) gang(dim:Two) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop gang(static:i, dim:Two) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop gang(dim:Two) gang(static:*) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop gang(dim:Two, static:*) + for(int i = 0; i < 5; ++i); + + // expected-error@+4{{OpenACC 'gang' clause may have at most one 'static' argument}} + // expected-note@+3{{previous expression is here}} + // expected-error@+2{{OpenACC 'gang' clause may have at most one 'dim' argument}} + // expected-note@+1{{previous expression is here}} +#pragma acc parallel loop gang(dim:Two, static:*, dim:1, static:i) + for(int i = 0; i < 5; ++i); +} + +void Parallel() { + ParallelTempl(); // expected-note{{in instantiation of function template}} + int i; + + // expected-error@+1{{'num' argument on 'gang' clause is not permitted on a 'parallel loop' construct}} +#pragma acc parallel loop gang(i) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'num' argument on 'gang' clause is not permitted on a 'parallel loop' construct}} +#pragma acc parallel loop gang(num:i) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{argument to 'gang' clause dimension must be a constant expression}} +#pragma acc parallel loop gang(dim:i) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 0}} +#pragma acc parallel loop gang(dim:0) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop gang(dim:2) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{argument to 'gang' clause dimension must be 1, 2, or 3: evaluated to 4}} +#pragma acc parallel loop gang(dim:4) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop gang(static:i) gang(dim:2) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop gang(static:i, dim:2) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop gang(dim:2) gang(static:*) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop gang(dim:2, static:*) + for(int i = 0; i < 5; ++i); + + // expected-error@+4{{OpenACC 'gang' clause may have at most one 'static' argument}} + // expected-note@+3{{previous expression is here}} + // expected-error@+2{{OpenACC 'gang' clause may have at most one 'dim' argument}} + // expected-note@+1{{previous expression is here}} +#pragma acc parallel loop gang(dim:2, static:*, dim:1, static:i) + for(int i = 0; i < 5; ++i); +} + +template +void StaticIsIntegralTempl() { + SomeS s; + // expected-error@+1{{OpenACC clause 'gang' requires expression of integer type ('S' invalid)}} +#pragma acc parallel loop gang(dim:2) gang(static:s) + for(int i = 0; i < 5; ++i); + + SomeC C; +#pragma acc parallel loop gang(dim:2) gang(static:C) + for(int i = 0; i < 5; ++i); + Int i; +#pragma acc parallel loop gang(dim:2) gang(static:i) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop gang(dim:2) gang(static:*) + for(int i = 0; i < 5; ++i); +} + +void StaticIsIntegral() { + StaticIsIntegralTempl();// expected-note{{in instantiation of function template}} + + S s; + // expected-error@+1{{OpenACC clause 'gang' requires expression of integer type ('S' invalid)}} +#pragma acc parallel loop gang(dim:2) gang(static:s) + for(int i = 0; i < 5; ++i); + + Converts C; +#pragma acc parallel loop gang(dim:2) gang(static:C) + for(int i = 0; i < 5; ++i); +} + +template +void SerialTempl() { + // expected-error@+1{{'num' argument on 'gang' clause is not permitted on a 'serial loop'}} +#pragma acc serial loop gang(I) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'num' argument on 'gang' clause is not permitted on a 'serial loop'}} +#pragma acc serial loop gang(num:I) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'dim' argument on 'gang' clause is not permitted on a 'serial loop'}} +#pragma acc serial loop gang(dim:I) + for(int i = 0; i < 5; ++i); + +#pragma acc serial loop gang(static:I) + for(int i = 0; i < 5; ++i); +} + +void Serial() { + SerialTempl<2>(); + + // expected-error@+1{{'num' argument on 'gang' clause is not permitted on a 'serial loop'}} +#pragma acc serial loop gang(1) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'num' argument on 'gang' clause is not permitted on a 'serial loop'}} +#pragma acc serial loop gang(num:1) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'dim' argument on 'gang' clause is not permitted on a 'serial loop'}} +#pragma acc serial loop gang(dim:1) + for(int i = 0; i < 5; ++i); + +#pragma acc serial loop gang(static:1) + for(int i = 0; i < 5; ++i); + + int i; +#pragma acc serial loop gang(static:i) + for(int i = 0; i < 5; ++i); +} + +template +void KernelsTempl() { + T t; + // expected-error@+1{{'dim' argument on 'gang' clause is not permitted on a 'kernels loop'}} +#pragma acc kernels loop gang(dim:t) + for(int i = 0; i < 5; ++i); + +#pragma acc kernels loop gang(static:t) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{'num_gangs' clause not allowed on a 'kernels loop' construct that has a 'gang' clause with a 'num' argument}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop gang(t) num_gangs(t) + for(int i = 0; i < 5; ++i); + + // OK, kernels loop should block this. +#pragma acc kernels num_gangs(t) +#pragma acc kernels loop gang(static:t) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{'num' argument to 'gang' clause not allowed on a 'kernels loop' construct that has a 'num_gangs' clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop num_gangs(t) gang(t) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{'num_gangs' clause not allowed on a 'kernels loop' construct that has a 'gang' clause with a 'num' argument}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop gang(num:t) num_gangs(t) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{'num' argument to 'gang' clause not allowed on a 'kernels loop' construct that has a 'num_gangs' clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop num_gangs(t) gang(num:t) + for(int i = 0; i < 5; ++i); +} + +void Kernels() { + KernelsTempl(); + + // expected-error@+1{{'dim' argument on 'gang' clause is not permitted on a 'kernels loop'}} +#pragma acc kernels loop gang(dim:1) + for(int i = 0; i < 5; ++i); + + unsigned t; +#pragma acc kernels loop gang(static:t) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{'num_gangs' clause not allowed on a 'kernels loop' construct that has a 'gang' clause with a 'num' argument}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop gang(t) num_gangs(t) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{'num' argument to 'gang' clause not allowed on a 'kernels loop' construct that has a 'num_gangs' clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop num_gangs(t) gang(t) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{'num_gangs' clause not allowed on a 'kernels loop' construct that has a 'gang' clause with a 'num' argument}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop gang(num:t) num_gangs(t) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{'num' argument to 'gang' clause not allowed on a 'kernels loop' construct that has a 'num_gangs' clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop num_gangs(t) gang(num:t) + for(int i = 0; i < 5; ++i); + + // OK, intervening compute/combined construct. +#pragma acc kernels loop gang(num:1) + for(int i = 0; i < 5; ++i) { +#pragma acc serial loop gang(static:1) + for(int i = 0; i < 5; ++i); + } +#pragma acc kernels loop gang(num:1) + for(int i = 0; i < 5; ++i) { +#pragma acc serial +#pragma acc loop gang(static:1) + for(int i = 0; i < 5; ++i); + } +#pragma acc kernels +#pragma acc loop gang(num:1) + for(int i = 0; i < 5; ++i) { +#pragma acc serial loop gang(static:1) + for(int i = 0; i < 5; ++i); + } + +#pragma acc kernels loop gang(num:1) + for(int i = 0; i < 5; ++i) { + // expected-error@+2{{loop with a 'gang' clause may not exist in the region of a 'gang' clause on a 'kernels loop' construct}} + // expected-note@-3{{previous clause is here}} +#pragma acc loop gang(static:1) + for(int i = 0; i < 5; ++i); + } + + // OK, on a different 'loop', not in the associated stmt. +#pragma acc kernels loop gang(num:1) + for(int i = 0; i < 5; ++i); +#pragma acc loop gang(static:1) + for(int i = 0; i < 5; ++i); + + // OK, on a different 'loop', not in the associated stmt. +#pragma acc kernels loop gang(num:1) + for(int i = 0; i < 5; ++i); +#pragma acc kernels loop gang(static:1) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{OpenACC 'gang' clause may have at most one unnamed or 'num' argument}} + // expected-note@+1{{previous expression is here}} +#pragma acc kernels loop gang(5, num:1) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{OpenACC 'gang' clause may have at most one unnamed or 'num' argument}} + // expected-note@+1{{previous expression is here}} +#pragma acc kernels loop gang(num:5, 1) + for(int i = 0; i < 5; ++i); + + // expected-error@+3{{OpenACC 'gang' clause may have at most one unnamed or 'num' argument}} + // expected-note@+2{{previous expression is here}} +#pragma acc kernels +#pragma acc kernels loop gang(num:5, num:1) + for(int i = 0; i < 5; ++i); +} + +void MaxOneEntry() { + // expected-error@+2{{OpenACC 'gang' clause may have at most one 'static' argument}} + // expected-note@+1{{previous expression is here}} +#pragma acc kernels loop gang(static: 1, static:1) + for(int i = 0; i < 5; ++i); + +#pragma acc kernels loop gang gang(static:1) + for(int i = 0; i < 5; ++i); +} + + diff --git a/clang/test/SemaOpenACC/combined-construct-if-clause.c b/clang/test/SemaOpenACC/combined-construct-if-clause.c index 563f1cd25377b..5580fdfe22b7b 100644 --- a/clang/test/SemaOpenACC/combined-construct-if-clause.c +++ b/clang/test/SemaOpenACC/combined-construct-if-clause.c @@ -43,8 +43,7 @@ void BoolExpr(int *I, float *F) { #pragma acc kernels loop if (*I < *F) for (unsigned i = 0; i < 5; ++i); - // expected-warning@+2{{OpenACC construct 'data' not yet implemented}} - // expected-warning@+1{{OpenACC clause 'if' not yet implemented}} + // expected-error@+1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} #pragma acc data if (*I < *F) for (unsigned i = 0; i < 5; ++i); #pragma acc parallel loop if (*I < *F) diff --git a/clang/test/SemaOpenACC/combined-construct-reduction-ast.cpp b/clang/test/SemaOpenACC/combined-construct-reduction-ast.cpp new file mode 100644 index 0000000000000..502b7a2613e40 --- /dev/null +++ b/clang/test/SemaOpenACC/combined-construct-reduction-ast.cpp @@ -0,0 +1,129 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +void NormalFunc(int i, float f) { + // CHECK: FunctionDecl{{.*}}NormalFunc + // CHECK-NEXT: ParmVarDecl + // CHECK-NEXT: ParmVarDecl + // CHECK-NEXT: CompoundStmt + +#pragma acc parallel loop reduction(+: i) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: reduction clause Operator: + + // CHECK-NEXT: DeclRefExpr{{.*}} 'int' lvalue ParmVar{{.*}} 'i' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc serial loop reduction(*: f) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop + // CHECK-NEXT: reduction clause Operator: * + // CHECK-NEXT: DeclRefExpr{{.*}} 'float' lvalue ParmVar{{.*}} 'f' 'float' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + +#pragma acc kernels loop reduction(max: i) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: reduction clause Operator: max + // CHECK-NEXT: DeclRefExpr{{.*}} 'int' lvalue ParmVar{{.*}} 'i' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + } + +template +void TemplFunc() { + // CHECK: FunctionTemplateDecl{{.*}}TemplFunc + // CHECK-NEXT: TemplateTypeParmDecl + + // Match the prototype: + // CHECK-NEXT: FunctionDecl{{.*}}TemplFunc + // CHECK-NEXT: CompoundStmt + + T t; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} t 'T' + +#pragma acc parallel loop reduction(+: t) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: reduction clause Operator: + + // CHECK-NEXT: DeclRefExpr{{.*}} 'T' lvalue Var{{.*}} 't' 'T' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc serial loop reduction(*: T::SomeFloat) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop + // CHECK-NEXT: reduction clause Operator: * + // CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '' lvalue + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'T' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + typename T::IntTy i; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} i 'typename T::IntTy' + +#pragma acc kernels loop reduction(max: i) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: reduction clause Operator: max + // CHECK-NEXT: DeclRefExpr{{.*}} 'typename T::IntTy' lvalue Var{{.*}} 'i' 'typename T::IntTy' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // Match the instantiation: + + // CHECK: FunctionDecl{{.*}}TemplFunc 'void ()' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'InstTy' + // CHECK-NEXT: RecordType{{.*}} 'InstTy' + // CHECK-NEXT: CXXRecord{{.*}} 'InstTy' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} used t 'InstTy' + // CHECK-NEXT: CXXConstructExpr{{.*}} 'InstTy' 'void () noexcept' + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: reduction clause Operator: + + // CHECK-NEXT: DeclRefExpr{{.*}} 'InstTy' lvalue Var{{.*}} 't' 'InstTy' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop + // CHECK-NEXT: reduction clause Operator: * + // CHECK-NEXT: DeclRefExpr{{.*}} 'const float' lvalue Var{{.*}} 'SomeFloat' 'const float' + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl{{.*}} i 'typename InstTy::IntTy':'int' + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: reduction clause Operator: max + // CHECK-NEXT: DeclRefExpr{{.*}} 'typename InstTy::IntTy':'int' lvalue Var{{.*}} 'i' 'typename InstTy::IntTy':'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +} + +struct InstTy { + using IntTy = int; + static constexpr float SomeFloat = 5.0; +}; + +void Instantiate() { + TemplFunc(); +} +#endif // PCH_HELPER diff --git a/clang/test/SemaOpenACC/combined-construct-reduction-clause.cpp b/clang/test/SemaOpenACC/combined-construct-reduction-clause.cpp new file mode 100644 index 0000000000000..082f1ed67a86f --- /dev/null +++ b/clang/test/SemaOpenACC/combined-construct-reduction-clause.cpp @@ -0,0 +1,169 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +struct CompositeOfScalars { + int I; + float F; + short J; + char C; + double D; + _Complex float CF; + _Complex double CD; +}; + +struct CompositeHasComposite { + int I; + float F; + short J; + char C; + double D; + _Complex float CF; + _Complex double CD; + struct CompositeOfScalars COS; // #COS_FIELD +}; + + // All of the type checking is done for compute and loop constructs, so only check the basics + the parts that are combined specific. +void uses(unsigned Parm) { + struct CompositeOfScalars CoS; + struct CompositeHasComposite ChC; + int I; + float F; + int Array[5]; + + // legal on all 3 kinds of combined constructs +#pragma acc parallel loop reduction(+:Parm) + for(int i = 0; i < 5; ++i); + +#pragma acc serial loop reduction(&: CoS, I, F) + for(int i = 0; i < 5; ++i); + +#pragma acc kernels loop reduction(min: CoS, Array[I], Array[0:I]) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{OpenACC 'reduction' composite variable must not have non-scalar field}} + // expected-note@#COS_FIELD{{invalid field is here}} +#pragma acc parallel loop reduction(&: ChC) + for(int i = 0; i < 5; ++i); + +#pragma acc kernels loop reduction(+:Parm) num_gangs(I) + for(int i = 0; i < 5; ++i); + // expected-error@+2{{OpenACC 'num_gangs' clause with more than 1 argument may not appear on a 'parallel loop' construct with a 'reduction' clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel loop reduction(+:Parm) num_gangs(I, I) + for(int i = 0; i < 5; ++i); + +#pragma acc kernels loop num_gangs(I) reduction(+:Parm) + for(int i = 0; i < 5; ++i); + // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel loop' construct with a 'num_gangs' clause with more than 1 argument}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel loop num_gangs(I, I) reduction(+:Parm) + for(int i = 0; i < 5; ++i); + + // Reduction cannot appear on a loop with a 'gang' of dim>1. +#pragma acc parallel loop gang(dim:1) reduction(+:Parm) + for(int i = 0; i < 5; ++i); + // expected-error@+2{{OpenACC 'reduction' clause cannot appear on the same 'parallel loop' construct as a 'gang' clause with a 'dim' value greater than 1}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel loop gang(dim:2) reduction(+:Parm) + for(int i = 0; i < 5; ++i); +#pragma acc parallel loop reduction(+:Parm) gang(dim:1) + for(int i = 0; i < 5; ++i); + // expected-error@+2{{OpenACC 'gang' clause with a 'dim' value greater than 1 cannot appear on the same 'parallel loop' construct as a 'reduction' clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel loop reduction(+:Parm) gang(dim:2) + for(int i = 0; i < 5; ++i); + + // Reduction cannot appear on a loop with a gang and a num_gangs with >1 + // explicit argument. +#pragma acc kernels loop num_gangs(I) reduction(+:Parm) gang + for(int i = 0; i < 5; ++i); +#pragma acc kernels loop num_gangs(I) gang reduction(+:Parm) + for(int i = 0; i < 5; ++i); +#pragma acc kernels loop reduction(+:Parm) num_gangs(I) gang + for(int i = 0; i < 5; ++i); +#pragma acc kernels loop reduction(+:Parm) gang num_gangs(I) + for(int i = 0; i < 5; ++i); +#pragma acc kernels loop gang num_gangs(I) reduction(+:Parm) + for(int i = 0; i < 5; ++i); +#pragma acc kernels loop gang reduction(+:Parm) num_gangs(I) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel loop' construct with a 'num_gangs' clause with more than 1 argument}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel loop num_gangs(I, I) reduction(+:Parm) gang + for(int i = 0; i < 5; ++i); + // expected-error@+3{{OpenACC 'reduction' clause cannot appear on the same 'parallel loop' construct as a 'gang' clause and a 'num_gangs' clause with more than one argument}} + // expected-note@+2{{previous clause is here}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel loop num_gangs(I, I) gang reduction(+:Parm) + for(int i = 0; i < 5; ++i); + // expected-error@+2{{OpenACC 'num_gangs' clause with more than 1 argument may not appear on a 'parallel loop' construct with a 'reduction' clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel loop reduction(+:Parm) num_gangs(I, I) gang + for(int i = 0; i < 5; ++i); + // expected-error@+3{{OpenACC 'reduction' clause cannot appear on the same 'parallel loop' construct as a 'gang' clause and a 'num_gangs' clause with more than one argument}} + // expected-note@+2{{previous clause is here}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel loop reduction(+:Parm) gang num_gangs(I, I) + for(int i = 0; i < 5; ++i); + // expected-error@+3{{OpenACC 'reduction' clause cannot appear on the same 'parallel loop' construct as a 'gang' clause and a 'num_gangs' clause with more than one argument}} + // expected-note@+2{{previous clause is here}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel loop gang num_gangs(I, I) reduction(+:Parm) + for(int i = 0; i < 5; ++i); + // expected-error@+3{{OpenACC 'reduction' clause cannot appear on the same 'parallel loop' construct as a 'gang' clause and a 'num_gangs' clause with more than one argument}} + // expected-note@+2{{previous clause is here}} + // expected-note@+1{{previous clause is here}} +#pragma acc parallel loop gang reduction(+:Parm) num_gangs(I, I) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop num_gangs(I) reduction(+:Parm) gang + for(int i = 0; i < 5; ++i); +#pragma acc parallel loop num_gangs(I) gang reduction(+:Parm) + for(int i = 0; i < 5; ++i); +#pragma acc parallel loop reduction(+:Parm) num_gangs(I) gang + for(int i = 0; i < 5; ++i); +#pragma acc parallel loop reduction(+:Parm) gang num_gangs(I) + for(int i = 0; i < 5; ++i); +#pragma acc parallel loop gang num_gangs(I) reduction(+:Parm) + for(int i = 0; i < 5; ++i); +#pragma acc parallel loop gang reduction(+:Parm) num_gangs(I) + for(int i = 0; i < 5; ++i); + +#pragma acc parallel loop reduction(+:I) + for(int i = 0; i < 5; ++i) { + // expected-error@+2{{OpenACC 'reduction' variable must have the same operator in all nested constructs (& vs +)}} + // expected-note@-3{{previous clause is here}} +#pragma acc loop reduction(&:I) + for(int i = 0; i < 5; ++i); + } +#pragma acc parallel loop reduction(+:I) + for(int i = 0; i < 5; ++i) { + // expected-error@+2{{OpenACC 'reduction' variable must have the same operator in all nested constructs (& vs +)}} + // expected-note@-3{{previous clause is here}} +#pragma acc parallel reduction(&:I) + for(int i = 0; i < 5; ++i); + } + +#pragma acc parallel loop reduction(+:I) + for(int i = 0; i < 5; ++i) { + // expected-error@+2{{OpenACC 'reduction' variable must have the same operator in all nested constructs (& vs +)}} + // expected-note@-3{{previous clause is here}} +#pragma acc parallel loop reduction(&:I) + for(int i = 0; i < 5; ++i); + } +#pragma acc loop reduction(+:I) + for(int i = 0; i < 5; ++i) { + // expected-error@+2{{OpenACC 'reduction' variable must have the same operator in all nested constructs (& vs +)}} + // expected-note@-3{{previous clause is here}} +#pragma acc parallel loop reduction(&:I) + for(int i = 0; i < 5; ++i); + } + +#pragma acc parallel reduction(+:I) + for(int i = 0; i < 5; ++i) { + // expected-error@+2{{OpenACC 'reduction' variable must have the same operator in all nested constructs (& vs +)}} + // expected-note@-3{{previous clause is here}} +#pragma acc parallel loop reduction(&:I) + for(int i = 0; i < 5; ++i); + } +} diff --git a/clang/test/SemaOpenACC/combined-construct-vector-ast.cpp b/clang/test/SemaOpenACC/combined-construct-vector-ast.cpp new file mode 100644 index 0000000000000..7b103021ccd55 --- /dev/null +++ b/clang/test/SemaOpenACC/combined-construct-vector-ast.cpp @@ -0,0 +1,176 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s +#ifndef PCH_HELPER +#define PCH_HELPER +void NormalUses() { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK-NEXT: CompoundStmt + + int Val; + +#pragma acc parallel loop vector + for(int i = 0; i < 5; ++i); + // CHECK: OpenACCCombinedConstruct{{.*}}parallel loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc parallel loop vector(Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}parallel loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc serial loop vector + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}serial loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc kernels loop vector + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}kernels loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc kernels loop vector(Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}kernels loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +} + +template +void TemplateUses(T Val) { + // CHECK: FunctionTemplateDecl{{.*}}TemplateUses + // CHECK-NEXT: TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'unsigned int' depth 0 index 1 One + // CHECK-NEXT: FunctionDecl{{.*}} TemplateUses 'void (T)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced Val 'T' + // CHECK-NEXT: CompoundStmt + + +#pragma acc parallel loop vector + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}parallel loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc parallel loop vector(Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}parallel loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'T' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc parallel loop vector(length:One) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}parallel loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: DeclRefExpr{{.*}}'One' 'unsigned int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc serial loop vector + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}serial loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc kernels loop vector + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}kernels loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc kernels loop vector(Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}kernels loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'T' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc kernels loop vector(length:One) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}kernels loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: DeclRefExpr{{.*}}'One' 'unsigned int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + + // Instantiation: + // CHECK-NEXT: FunctionDecl{{.*}} used TemplateUses 'void (int)' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: TemplateArgument integral '1U' + // CHECK-NEXT: ParmVarDecl{{.*}} used Val 'int' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}parallel loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}parallel loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}} 'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}parallel loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: SubstNonTypeTemplateParmExpr + // CHECK-NEXT: NonTypeTemplateParmDecl + // CHECK-NEXT: IntegerLiteral{{.*}}1 + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}serial loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}kernels loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}kernels loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}} 'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}}kernels loop + // CHECK-NEXT: vector clause + // CHECK-NEXT: SubstNonTypeTemplateParmExpr + // CHECK-NEXT: NonTypeTemplateParmDecl + // CHECK-NEXT: IntegerLiteral{{.*}}1 + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +} + +void inst() { + TemplateUses(5); +} + +#endif // PCH_HELPER diff --git a/clang/test/SemaOpenACC/combined-construct-vector-clause.cpp b/clang/test/SemaOpenACC/combined-construct-vector-clause.cpp new file mode 100644 index 0000000000000..f96a36c1e395b --- /dev/null +++ b/clang/test/SemaOpenACC/combined-construct-vector-clause.cpp @@ -0,0 +1,171 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +template +void TemplUses(T t) { + +#pragma acc parallel loop vector + for(int j = 0; j < 5; ++j); + +#pragma acc parallel loop vector(I) + for(int j = 0; j < 5; ++j); + +#pragma acc parallel loop vector(length:I) + for(int j = 0; j < 5; ++j); + +#pragma acc serial loop vector + for(int j = 0; j < 5; ++j); + + // expected-error@+1{{'length' argument on 'vector' clause is not permitted on a 'serial loop' construct}} +#pragma acc serial loop vector(I) + for(int j = 0; j < 5; ++j); + + // expected-error@+1{{'length' argument on 'vector' clause is not permitted on a 'serial loop' construct}} +#pragma acc serial loop vector(length:I) + for(int j = 0; j < 5; ++j); + +#pragma acc kernels loop vector + for(int j = 0; j < 5; ++j); + +#pragma acc kernels loop vector(I) + for(int j = 0; j < 5; ++j); + +#pragma acc kernels loop vector(length:I) + for(int j = 0; j < 5; ++j); + +#pragma acc kernels loop vector vector_length(t) + for(int j = 0; j < 5; ++j); + +#pragma acc kernels loop vector_length(t) vector + for(int j = 0; j < 5; ++j); + + // expected-error@+2{{'vector_length' clause not allowed on a 'kernels loop' construct that has a 'vector' clause with an argument}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop vector(I) vector_length(t) + for(int j = 0; j < 5; ++j); + + // expected-error@+2{{'length' argument to 'vector' clause not allowed on a 'kernels loop' construct that has a 'vector_length' clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop vector_length(t) vector(I) + for(int j = 0; j < 5; ++j); + +#pragma acc parallel loop vector + for(int j = 0; j < 5; ++j) { + // expected-error@+4{{loop with a 'vector' clause may not exist in the region of a 'vector' clause}} + // expected-error@+3{{loop with a 'worker' clause may not exist in the region of a 'vector' clause}} + // expected-error@+2{{loop with a 'gang' clause may not exist in the region of a 'vector' clause}} + // expected-note@-5 3{{previous clause is here}} +#pragma acc loop vector worker, gang + for(int j = 0; j < 5; ++j); + } +#pragma acc parallel loop vector + for(int j = 0; j < 5; ++j) { +#pragma acc serial loop vector worker, gang + for(int j = 0; j < 5; ++j); + } + +#pragma acc loop vector + for(int j = 0; j < 5; ++j) { +#pragma acc serial loop vector worker, gang + for(int j = 0; j < 5; ++j); + } + +#pragma acc kernels vector_length(t) + for(int j = 0; j < 5; ++j) { + // expected-error@+1{{'length' argument on 'vector' clause is not permitted on a 'serial loop' construct}} +#pragma acc serial loop vector(I) + for(int j = 0; j < 5; ++j); + } + +#pragma acc kernels vector_length(t) + for(int j = 0; j < 5; ++j) { +#pragma acc parallel loop vector(I) + for(int j = 0; j < 5; ++j); + } +} + +void uses() { + TemplUses(5); + + unsigned I; + int t; + +#pragma acc parallel loop vector + for(int j = 0; j < 5; ++j); + +#pragma acc parallel loop vector(I) + for(int j = 0; j < 5; ++j); + +#pragma acc parallel loop vector(length:I) + for(int j = 0; j < 5; ++j); + +#pragma acc serial loop vector + for(int j = 0; j < 5; ++j); + + // expected-error@+1{{'length' argument on 'vector' clause is not permitted on a 'serial loop' construct}} +#pragma acc serial loop vector(I) + for(int j = 0; j < 5; ++j); + + // expected-error@+1{{'length' argument on 'vector' clause is not permitted on a 'serial loop' construct}} +#pragma acc serial loop vector(length:I) + for(int j = 0; j < 5; ++j); + +#pragma acc kernels loop vector + for(int j = 0; j < 5; ++j); + +#pragma acc kernels loop vector(I) + for(int j = 0; j < 5; ++j); + +#pragma acc kernels loop vector(length:I) + for(int j = 0; j < 5; ++j); + +#pragma acc kernels loop vector vector_length(t) + for(int j = 0; j < 5; ++j); + +#pragma acc kernels loop vector_length(t) vector + for(int j = 0; j < 5; ++j); + + // expected-error@+2{{'vector_length' clause not allowed on a 'kernels loop' construct that has a 'vector' clause with an argument}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop vector(I) vector_length(t) + for(int j = 0; j < 5; ++j); + + // expected-error@+2{{'length' argument to 'vector' clause not allowed on a 'kernels loop' construct that has a 'vector_length' clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop vector_length(t) vector(I) + for(int j = 0; j < 5; ++j); + +#pragma acc parallel loop vector + for(int j = 0; j < 5; ++j) { + // expected-error@+4{{loop with a 'vector' clause may not exist in the region of a 'vector' clause}} + // expected-error@+3{{loop with a 'worker' clause may not exist in the region of a 'vector' clause}} + // expected-error@+2{{loop with a 'gang' clause may not exist in the region of a 'vector' clause}} + // expected-note@-5 3{{previous clause is here}} +#pragma acc loop vector worker, gang + for(int j = 0; j < 5; ++j); + } +#pragma acc parallel loop vector + for(int j = 0; j < 5; ++j) { +#pragma acc serial loop vector worker, gang + for(int j = 0; j < 5; ++j); + } + +#pragma acc loop vector + for(int j = 0; j < 5; ++j) { +#pragma acc serial loop vector worker, gang + for(int j = 0; j < 5; ++j); + } + +#pragma acc kernels vector_length(t) + for(int j = 0; j < 5; ++j) { +#pragma acc parallel loop vector(I) + for(int j = 0; j < 5; ++j); + } + +#pragma acc kernels vector_length(t) + for(int j = 0; j < 5; ++j) { + // expected-error@+1{{'length' argument on 'vector' clause is not permitted on a 'serial loop' construct}} +#pragma acc serial loop vector(I) + for(int j = 0; j < 5; ++j); + } +} + diff --git a/clang/test/SemaOpenACC/combined-construct-worker-ast.cpp b/clang/test/SemaOpenACC/combined-construct-worker-ast.cpp new file mode 100644 index 0000000000000..6ac0fdb35709f --- /dev/null +++ b/clang/test/SemaOpenACC/combined-construct-worker-ast.cpp @@ -0,0 +1,135 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s +#ifndef PCH_HELPER +#define PCH_HELPER +void NormalUses() { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK-NEXT: CompoundStmt + + int Val; + +#pragma acc parallel loop worker + for(int i = 0; i < 5; ++i); + // CHECK: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +#pragma acc serial loop worker + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc kernels loop worker(Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}} 'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +#pragma acc kernels loop worker(num:Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}} 'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +} + +template +void TemplateUses(T Val) { + // CHECK: FunctionTemplateDecl{{.*}}TemplateUses + // CHECK-NEXT: TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'unsigned int' depth 0 index 1 One + // CHECK-NEXT: FunctionDecl{{.*}} TemplateUses 'void (T)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced Val 'T' + // CHECK-NEXT: CompoundStmt + +#pragma acc parallel loop worker + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +#pragma acc serial loop worker + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc kernels loop worker(Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'T' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +#pragma acc kernels loop worker(num:Val) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'T' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +#pragma acc kernels loop worker(num:One) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: DeclRefExpr{{.*}}'One' 'unsigned int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // Instantiation: + // CHECK-NEXT: FunctionDecl{{.*}} used TemplateUses 'void (int)' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: TemplateArgument integral '1U' + // CHECK-NEXT: ParmVarDecl{{.*}} used Val 'int' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} parallel loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} serial loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'Val' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCCombinedConstruct{{.*}} kernels loop + // CHECK-NEXT: worker clause + // CHECK-NEXT: SubstNonTypeTemplateParmExpr + // CHECK-NEXT: NonTypeTemplateParmDecl + // CHECK-NEXT: IntegerLiteral{{.*}}'unsigned int' 1 + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +} + +void inst() { + TemplateUses(5); +} + +#endif // PCH_HELPER diff --git a/clang/test/SemaOpenACC/combined-construct-worker-clause.cpp b/clang/test/SemaOpenACC/combined-construct-worker-clause.cpp new file mode 100644 index 0000000000000..1351f9ea0c69c --- /dev/null +++ b/clang/test/SemaOpenACC/combined-construct-worker-clause.cpp @@ -0,0 +1,150 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +template +void TemplUses() { + +#pragma acc parallel loop worker + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{expected expression}} +#pragma acc parallel loop worker() + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'num' argument on 'worker' clause is not permitted on a 'parallel loop' construct}} +#pragma acc parallel loop worker(I) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'num' argument on 'worker' clause is not permitted on a 'parallel loop' construct}} +#pragma acc parallel loop worker(num:I) + for(int i = 0; i < 5; ++i); + +#pragma acc serial loop worker + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{expected expression}} +#pragma acc serial loop worker() + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'num' argument on 'worker' clause is not permitted on a 'serial loop' construct}} +#pragma acc serial loop worker(I) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'num' argument on 'worker' clause is not permitted on a 'serial loop' construct}} +#pragma acc serial loop worker(num:I) + for(int i = 0; i < 5; ++i); + +#pragma acc kernels loop worker(I) + for(int i = 0; i < 5; ++i); + +#pragma acc kernels loop worker(num:I) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{'num' argument to 'worker' clause not allowed on a 'kernels loop' construct that has a 'num_workers' clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop num_workers(1) worker(num:I) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{'num_workers' clause not allowed on a 'kernels loop' construct that has a 'worker' clause with an argument}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop worker(num:I) num_workers(1) + for(int i = 0; i < 5; ++i); +} + +void NormalUses() { + TemplUses<4>(); + + int I; +#pragma acc parallel loop worker + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{expected expression}} +#pragma acc parallel loop worker() + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'num' argument on 'worker' clause is not permitted on a 'parallel loop' construct}} +#pragma acc parallel loop worker(I) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'num' argument on 'worker' clause is not permitted on a 'parallel loop' construct}} +#pragma acc parallel loop worker(num:I) + for(int i = 0; i < 5; ++i); + +#pragma acc serial loop worker + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{expected expression}} +#pragma acc serial loop worker() + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'num' argument on 'worker' clause is not permitted on a 'serial loop' construct}} +#pragma acc serial loop worker(I) + for(int i = 0; i < 5; ++i); + + // expected-error@+1{{'num' argument on 'worker' clause is not permitted on a 'serial loop' construct}} +#pragma acc serial loop worker(num:I) + for(int i = 0; i < 5; ++i); + +#pragma acc kernels loop worker(I) + for(int i = 0; i < 5; ++i); + +#pragma acc kernels loop worker(num:I) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{'num' argument to 'worker' clause not allowed on a 'kernels loop' construct that has a 'num_workers' clause}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop num_workers(1) worker(num:I) + for(int i = 0; i < 5; ++i); + + // expected-error@+2{{'num_workers' clause not allowed on a 'kernels loop' construct that has a 'worker' clause with an argument}} + // expected-note@+1{{previous clause is here}} +#pragma acc kernels loop worker(num:I) num_workers(1) + for(int i = 0; i < 5; ++i); + + // OK, kernels loop is a new compute construct +#pragma acc kernels num_workers(1) + for(int i = 0; i < 5; ++i) { +#pragma acc kernels loop worker(num:1) + for(int i = 0; i < 5; ++i); + } +#pragma acc kernels loop num_workers(1) + for(int i = 0; i < 5; ++i) { +#pragma acc kernels loop worker(num:1) + for(int i = 0; i < 5; ++i); + } + +#pragma acc kernels loop num_workers(1) + for(int i = 0; i < 5; ++i) { + // expected-error@+2{{'num' argument to 'worker' clause not allowed on a 'loop' construct associated with a 'kernels loop' construct that has a 'num_workers' clause}} + // expected-note@-3{{previous clause is here}} +#pragma acc loop worker(num:1) + for(int i = 0; i < 5; ++i); + } + +#pragma acc parallel loop worker + for(int i = 0; i < 5; ++i) { + // expected-error@+4{{loop with a 'gang' clause may not exist in the region of a 'worker' clause}} + // expected-note@-3{{previous clause is here}} + // expected-error@+2{{loop with a 'worker' clause may not exist in the region of a 'worker' clause}} + // expected-note@-5{{previous clause is here}} +#pragma acc loop gang, worker, vector + for(int i = 0; i < 5; ++i); + } +#pragma acc kernels loop worker + for(int i = 0; i < 5; ++i) { + // expected-error@+4{{loop with a 'gang' clause may not exist in the region of a 'worker' clause}} + // expected-note@-3{{previous clause is here}} + // expected-error@+2{{loop with a 'worker' clause may not exist in the region of a 'worker' clause}} + // expected-note@-5{{previous clause is here}} +#pragma acc loop gang, worker, vector + for(int i = 0; i < 5; ++i); + } +#pragma acc serial loop worker + for(int i = 0; i < 5; ++i) { + // expected-error@+4{{loop with a 'gang' clause may not exist in the region of a 'worker' clause}} + // expected-note@-3{{previous clause is here}} + // expected-error@+2{{loop with a 'worker' clause may not exist in the region of a 'worker' clause}} + // expected-note@-5{{previous clause is here}} +#pragma acc loop gang, worker, vector + for(int i = 0; i < 5; ++i); + } +} diff --git a/clang/test/SemaOpenACC/compute-construct-default-clause.c b/clang/test/SemaOpenACC/compute-construct-default-clause.c index 70e29f3e8ac05..dfa5cd3f1c0d3 100644 --- a/clang/test/SemaOpenACC/compute-construct-default-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-default-clause.c @@ -28,8 +28,6 @@ void SingleOnly() { #pragma acc kernels default(none) for(int i = 0; i < 5; ++i); - // expected-warning@+2{{OpenACC construct 'data' not yet implemented}} - // expected-warning@+1{{OpenACC clause 'default' not yet implemented}} #pragma acc data default(none) while(0); diff --git a/clang/test/SemaOpenACC/compute-construct-device_type-clause.c b/clang/test/SemaOpenACC/compute-construct-device_type-clause.c index 0ae972d2a99ff..c1a77abf5c3f1 100644 --- a/clang/test/SemaOpenACC/compute-construct-device_type-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-device_type-clause.c @@ -34,22 +34,20 @@ void uses() { #pragma acc kernels dtype(MACRO) while(1); - // expected-error@+2{{OpenACC 'device_type' clause is not valid on 'enter data' directive}} - // expected-warning@+1{{OpenACC construct 'enter data' not yet implemented}} + // expected-error@+2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} + // expected-error@+1{{OpenACC 'device_type' clause is not valid on 'enter data' directive}} #pragma acc enter data device_type(I) - // expected-error@+2{{OpenACC 'dtype' clause is not valid on 'enter data' directive}} - // expected-warning@+1{{OpenACC construct 'enter data' not yet implemented}} + // expected-error@+2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} + // expected-error@+1{{OpenACC 'dtype' clause is not valid on 'enter data' directive}} #pragma acc enter data dtype(I) // Only 'async', 'wait', num_gangs', 'num_workers', 'vector_length' allowed after 'device_type'. - // expected-error@+2{{OpenACC clause 'finalize' may not follow a 'device_type' clause in a 'kernels' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'kernels' directive}} #pragma acc kernels device_type(*) finalize while(1); - // expected-error@+2{{OpenACC clause 'if_present' may not follow a 'device_type' clause in a 'kernels' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'kernels' directive}} #pragma acc kernels device_type(*) if_present while(1); // expected-error@+1{{OpenACC 'seq' clause is not valid on 'kernels' directive}} @@ -95,20 +93,17 @@ void uses() { // expected-note@+1{{previous clause is here}} #pragma acc kernels device_type(*) present_or_copy(Var) while(1); - // expected-error@+2{{OpenACC clause 'use_device' may not follow a 'device_type' clause in a 'kernels' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'kernels' directive}} #pragma acc kernels device_type(*) use_device(Var) while(1); // expected-error@+2{{OpenACC clause 'attach' may not follow a 'device_type' clause in a 'kernels' construct}} // expected-note@+1{{previous clause is here}} #pragma acc kernels device_type(*) attach(Var) while(1); - // expected-error@+2{{OpenACC clause 'delete' may not follow a 'device_type' clause in a 'kernels' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'kernels' directive}} #pragma acc kernels device_type(*) delete(Var) while(1); - // expected-error@+2{{OpenACC clause 'detach' may not follow a 'device_type' clause in a 'kernels' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'kernels' directive}} #pragma acc kernels device_type(*) detach(Var) while(1); // expected-error@+2{{OpenACC clause 'device' may not follow a 'device_type' clause in a 'kernels' construct}} diff --git a/clang/test/SemaOpenACC/compute-construct-if-clause.c b/clang/test/SemaOpenACC/compute-construct-if-clause.c index 7cdc35275acce..c0ea88f06284d 100644 --- a/clang/test/SemaOpenACC/compute-construct-if-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-if-clause.c @@ -43,8 +43,7 @@ void BoolExpr(int *I, float *F) { #pragma acc kernels if (*I < *F) while(0); - // expected-warning@+2{{OpenACC construct 'data' not yet implemented}} - // expected-warning@+1{{OpenACC clause 'if' not yet implemented}} + // expected-error@+1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} #pragma acc data if (*I < *F) while(0); #pragma acc parallel loop if (*I < *F) diff --git a/clang/test/SemaOpenACC/compute-construct-reduction-clause.c b/clang/test/SemaOpenACC/compute-construct-reduction-clause.c index 80310f0e7afc6..fcc4ca2655c20 100644 --- a/clang/test/SemaOpenACC/compute-construct-reduction-clause.c +++ b/clang/test/SemaOpenACC/compute-construct-reduction-clause.c @@ -41,12 +41,12 @@ void uses(unsigned Parm) { #pragma acc parallel num_gangs(IVar) reduction(+:IVar) while (1); - // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument, have 2}} + // expected-error@+2{{OpenACC 'num_gangs' clause with more than 1 argument may not appear on a 'parallel' construct with a 'reduction' clause}} // expected-note@+1{{previous clause is here}} #pragma acc parallel reduction(+:Parm) num_gangs(Parm, IVar) while (1); - // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument, have 2}} + // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument}} // expected-note@+1{{previous clause is here}} #pragma acc parallel num_gangs(Parm, IVar) reduction(+:Var) while (1); diff --git a/clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp b/clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp index 532dbb2387165..7372f683e2eb3 100644 --- a/clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp +++ b/clang/test/SemaOpenACC/compute-construct-reduction-clause.cpp @@ -41,12 +41,12 @@ void uses(unsigned Parm) { #pragma acc parallel num_gangs(IVar) reduction(+:Var) while (1); - // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument, have 2}} + // expected-error@+2{{OpenACC 'num_gangs' clause with more than 1 argument may not appear on a 'parallel' construct with a 'reduction' clause}} // expected-note@+1{{previous clause is here}} #pragma acc parallel reduction(+:Parm) num_gangs(Parm, IVar) while (1); - // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument, have 2}} + // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument}} // expected-note@+1{{previous clause is here}} #pragma acc parallel num_gangs(Parm, IVar) reduction(+:Var) while (1); @@ -116,12 +116,12 @@ void TemplUses(T Parm, U CoS, V ChC) { #pragma acc parallel num_gangs(Var) reduction(+:Var) while (1); - // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument, have 2}} + // expected-error@+2{{OpenACC 'num_gangs' clause with more than 1 argument may not appear on a 'parallel' construct with a 'reduction' clause}} // expected-note@+1{{previous clause is here}} #pragma acc parallel reduction(+:Parm) num_gangs(Parm, Var) while (1); - // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument, have 2}} + // expected-error@+2{{OpenACC 'reduction' clause may not appear on a 'parallel' construct with a 'num_gangs' clause with more than 1 argument}} // expected-note@+1{{previous clause is here}} #pragma acc parallel num_gangs(Parm, Var) reduction(+:Var) while (1); diff --git a/clang/test/SemaOpenACC/data-construct-ast.cpp b/clang/test/SemaOpenACC/data-construct-ast.cpp new file mode 100644 index 0000000000000..5abd142b237a2 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-ast.cpp @@ -0,0 +1,109 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +void NormalFunc() { + // CHECK-LABEL: NormalFunc + // CHECK-NEXT: CompoundStmt + + int Var; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + + // TODO OpenACC: these constructs require the clauses to be legal, but we + // don't have the clauses implemented yet. As we implement them, they needed + // to be added to the 'check' lines. + +#pragma acc data default(none) + while (Var); + // CHECK-NEXT: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: default(none) + // CHECK-NEXT: WhileStmt + // CHECK: NullStmt +#pragma acc enter data copyin(Var) + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Var' 'int' +#pragma acc exit data copyout(Var) + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Var' 'int' +#pragma acc host_data use_device(Var) + while (Var); + // CHECK-NEXT: OpenACCHostDataConstruct{{.*}} host_data + // CHECK-NEXT: use_device clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Var' 'int' + // CHECK-NEXT: WhileStmt + // CHECK: NullStmt +} + +template +void TemplFunc() { + // CHECK-LABEL: FunctionTemplateDecl {{.*}}TemplFunc + // CHECK-NEXT: TemplateTypeParmDecl + // CHECK-NEXT: FunctionDecl{{.*}}TemplFunc + // CHECK-NEXT: CompoundStmt + + T Var; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + +#pragma acc data default(none) + while (Var); + // CHECK-NEXT: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: default(none) + // CHECK-NEXT: WhileStmt + // CHECK: NullStmt +#pragma acc enter data copyin(Var) + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Var' 'T' +#pragma acc exit data copyout(Var) + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Var' 'T' +#pragma acc host_data use_device(Var) + while (Var); + // CHECK-NEXT: OpenACCHostDataConstruct{{.*}} host_data + // CHECK-NEXT: use_device clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Var' 'T' + // CHECK-NEXT: WhileStmt + // CHECK: NullStmt + + // Instantiation: + // CHECK-NEXT: FunctionDecl{{.*}} TemplFunc 'void ()' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + + // CHECK-NEXT: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: default(none) + // CHECK-NEXT: WhileStmt + // CHECK: NullStmt + + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Var' 'int' + + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Var' 'int' + + // CHECK-NEXT: OpenACCHostDataConstruct{{.*}} host_data + // CHECK-NEXT: use_device clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Var' 'int' + // CHECK-NEXT: WhileStmt + // CHECK: NullStmt +} +void use() { + TemplFunc(); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-async-ast.cpp b/clang/test/SemaOpenACC/data-construct-async-ast.cpp new file mode 100644 index 0000000000000..fb6a37108ae4e --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-async-ast.cpp @@ -0,0 +1,78 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s +#ifndef PCH_HELPER +#define PCH_HELPER + +int some_int(); + +template +void TemplUses() { + // CHECK: FunctionTemplateDecl{{.*}}TemplUses + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}T + // CHECK-NEXT: FunctionDecl{{.*}}TemplUses + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + T t; + +#pragma acc data default(none) async(some_int()) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: default(none) + // CHECK-NEXT: async clause + // CHECK-NEXT: CallExpr{{.*}}'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'some_int' 'int ()' + // CHECK-NEXT: NullStmt +#pragma acc enter data copyin(t) async(T{}) + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}}enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'t' 'T' + // CHECK-NEXT: async clause + // CHECK-NEXT: CXXUnresolvedConstructExpr{{.*}} 'T' 'T' list + // CHECK-NEXT: InitListExpr{{.*}}'void' +#pragma acc exit data copyout(t) async + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'t' 'T' + // CHECK-NEXT: async clause + + // Instantiations + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void ()' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + + // CHECK-NEXT: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: default(none) + // CHECK-NEXT: async clause + // CHECK-NEXT: CallExpr{{.*}}'int' + // CHECK-NEXT: ImplicitCastExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'some_int' 'int ()' + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}}enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'t' 'int' + // CHECK-NEXT: async clause + // CHECK-NEXT: CXXFunctionalCastExpr + // CHECK-NEXT: InitListExpr{{.*}}'int' + + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'t' 'int' + // CHECK-NEXT: async clause +} +void Inst() { + TemplUses(); +} + + +#endif // PCH_HELPER diff --git a/clang/test/SemaOpenACC/data-construct-async-clause.c b/clang/test/SemaOpenACC/data-construct-async-clause.c new file mode 100644 index 0000000000000..3c9fbae0d9875 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-async-clause.c @@ -0,0 +1,34 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +void Test() { + int I; + struct NotConvertible{} NC; + // No special rules for this clause on the data constructs, so not much to + // test that isn't covered by combined/compute. +#pragma acc data copyin(I) async(I) + ; +#pragma acc enter data copyin(I) async(I) +#pragma acc exit data copyout(I) async(I) + // expected-error@+1{{OpenACC 'async' clause is not valid on 'host_data' directive}} +#pragma acc host_data use_device(I) async(I) + ; + + // expected-error@+1{{OpenACC clause 'async' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc data copyin(NC) async(NC) + ; + // expected-error@+1{{OpenACC clause 'async' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc enter data copyin(NC) async(NC) + // expected-error@+1{{OpenACC clause 'async' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc exit data copyout(NC) async(NC) + // expected-error@+1{{OpenACC clause 'async' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc host_data use_device(NC) async(NC) + ; + + // expected-error@+2{{OpenACC 'async' clause cannot appear more than once on a 'data' directive}} + // expected-note@+1{{previous clause is here}} +#pragma acc data copyin(I) async(I) async(I) + ; + // expected-error@+2{{expected ')'}} + // expected-note@+1{{to match this '('}} +#pragma acc enter data copyin(I) async(I, I) +} diff --git a/clang/test/SemaOpenACC/data-construct-attach-ast.cpp b/clang/test/SemaOpenACC/data-construct-attach-ast.cpp new file mode 100644 index 0000000000000..f480e8bb61a70 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-attach-ast.cpp @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +int Global; +short GlobalArray[5]; + +void NormalUses(float *PointerParam) { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK: ParmVarDecl + // CHECK-NEXT: CompoundStmt + +#pragma acc data default(present) attach(PointerParam) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: default(present) + // CHECK-NEXT: attach clause + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}} 'PointerParam' 'float *' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +} + +template +void TemplUses(T *t) { + // CHECK-NEXT: FunctionTemplateDecl + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 0 T + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T *)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T *' + // CHECK-NEXT: CompoundStmt + +#pragma acc data default(present) attach(t) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: default(present) + // CHECK-NEXT: attach clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T *' lvalue ParmVar{{.*}} 't' 'T *' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + + // Check the instantiated versions of the above. + // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int *)' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int *' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: default(present) + // CHECK-NEXT: attach clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 't' 'int *' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +} + +void Inst() { + int i; + TemplUses(&i); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-attach-clause.c b/clang/test/SemaOpenACC/data-construct-attach-clause.c new file mode 100644 index 0000000000000..0bc02563ff695 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-attach-clause.c @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +struct S { + int IntMem; + int *PtrMem; +}; + +void uses() { + int LocalInt; + int *LocalPtr; + int Array[5]; + int *PtrArray[5]; + struct S s; + + // expected-error@+1{{expected pointer in 'attach' clause, type is 'int'}} +#pragma acc data default(none) attach(LocalInt) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data default(none) attach(&LocalInt) + ; + + + // expected-error@+1{{expected pointer in 'attach' clause, type is 'int[5]'}} +#pragma acc enter data copyin(LocalInt) attach(Array) + + // expected-error@+1{{expected pointer in 'attach' clause, type is 'int'}} +#pragma acc data default(none) attach(Array[0]) + ; + + // expected-error@+2{{OpenACC sub-array is not allowed here}} + // expected-note@+1{{expected variable of pointer type}} +#pragma acc data default(none) attach(Array[0:1]) + ; + + // expected-error@+1{{expected pointer in 'attach' clause, type is 'int *[5]'}} +#pragma acc data default(none) attach(PtrArray) + ; + +#pragma acc data default(none) attach(PtrArray[0]) + ; + + // expected-error@+2{{OpenACC sub-array is not allowed here}} + // expected-note@+1{{expected variable of pointer type}} +#pragma acc data default(none) attach(PtrArray[0:1]) + ; + + // expected-error@+1{{expected pointer in 'attach' clause, type is 'struct S'}} +#pragma acc data default(none) attach(s) + ; + + // expected-error@+1{{expected pointer in 'attach' clause, type is 'int'}} +#pragma acc data default(none) attach(s.IntMem) + ; + +#pragma acc data default(none) attach(s.PtrMem) + ; + + // expected-error@+1{{OpenACC 'attach' clause is not valid on 'exit data' directive}} +#pragma acc exit data copyout(LocalInt) attach(PtrArray[0]) + // expected-error@+1{{OpenACC 'attach' clause is not valid on 'host_data' directive}} +#pragma acc host_data use_device(LocalInt) attach(PtrArray[0]) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-copy-ast.cpp b/clang/test/SemaOpenACC/data-construct-copy-ast.cpp new file mode 100644 index 0000000000000..de067f00a2b29 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-copy-ast.cpp @@ -0,0 +1,93 @@ +// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +int Global; +short GlobalArray[5]; + +void NormalUses(float *PointerParam) { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK: ParmVarDecl + // CHECK-NEXT: CompoundStmt +#pragma acc data copy(GlobalArray) pcopy(PointerParam[Global]) present_or_copy(Global) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: copy clause + // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]' + // CHECK-NEXT: pcopy clause + // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: present_or_copy clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: NullStmt +} +template +void TemplUses(T t, U u) { + // CHECK-NEXT: FunctionTemplateDecl + // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U' + // CHECK-NEXT: CompoundStmt + +#pragma acc data copy(t) pcopy(NTTP, u) present_or_copy(u[0:t]) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: copy clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: pcopy clause + // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &' + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: present_or_copy clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: NullStmt + + // Check the instantiated versions of the above. + // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation + // CHECK-NEXT: TemplateArgument decl + // CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: TemplateArgument type 'int *' + // CHECK-NEXT: PointerType{{.*}} 'int *' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used u 'int *' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: copy clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: pcopy clause + // CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: present_or_copy clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: NullStmt +} +void Inst() { + static constexpr unsigned CEVar = 1; + int i; + TemplUses(i, &i); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-copy-clause.c b/clang/test/SemaOpenACC/data-construct-copy-clause.c new file mode 100644 index 0000000000000..882a0bc87e003 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-copy-clause.c @@ -0,0 +1,69 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +typedef struct IsComplete { + struct S { int A; } CompositeMember; + int ScalarMember; + float ArrayMember[5]; + void *PointerMember; +} Complete; +void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) { + int LocalInt; + short *LocalPointer; + float LocalArray[5]; + Complete LocalComposite; + // Check Appertainment: +#pragma acc data copy(LocalInt) + ; + + // expected-warning@+1{{OpenACC clause name 'pcopy' is a deprecated clause name and is now an alias for 'copy'}} +#pragma acc data pcopy(LocalInt) + ; + + // expected-warning@+1{{OpenACC clause name 'present_or_copy' is a deprecated clause name and is now an alias for 'copy'}} +#pragma acc data present_or_copy(LocalInt) + ; + + // Valid cases: +#pragma acc data copy(LocalInt, LocalPointer, LocalArray) + ; +#pragma acc data copy(LocalArray[2:1]) + ; + +#pragma acc data copy(LocalComposite.ScalarMember, LocalComposite.ScalarMember) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copy(1 + IntParam) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copy(+IntParam) + ; + + // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} +#pragma acc data copy(PointerParam[2:]) + ; + + // expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} +#pragma acc data copy(ArrayParam[2:5]) + ; + + // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copy((float*)ArrayParam[2:5]) + ; + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copy((float)ArrayParam[2]) + ; + + // expected-error@+2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} + // expected-error@+1{{OpenACC 'copy' clause is not valid on 'enter data' directive}} +#pragma acc enter data copy(LocalInt) + // expected-error@+2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} + // expected-error@+1{{OpenACC 'pcopy' clause is not valid on 'exit data' directive}} +#pragma acc exit data pcopy(LocalInt) + // expected-error@+2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} + // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'host_data' directive}} +#pragma acc host_data present_or_copy(LocalInt) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-copyin-ast.cpp b/clang/test/SemaOpenACC/data-construct-copyin-ast.cpp new file mode 100644 index 0000000000000..fd21d60c84431 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-copyin-ast.cpp @@ -0,0 +1,137 @@ +// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +int Global; +short GlobalArray[5]; +void NormalUses(float *PointerParam) { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK: ParmVarDecl + // CHECK-NEXT: CompoundStmt + +#pragma acc data copyin(GlobalArray) pcopyin(readonly:PointerParam[Global]) present_or_copyin(Global) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]' + // CHECK-NEXT: pcopyin clause : readonly + // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: present_or_copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: NullStmt + +#pragma acc enter data copyin(GlobalArray) pcopyin(readonly:PointerParam[Global]) present_or_copyin(Global) + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]' + // CHECK-NEXT: pcopyin clause : readonly + // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: present_or_copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' +} + +template +void TemplUses(T t, U u) { + // CHECK-NEXT: FunctionTemplateDecl + // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U' + // CHECK-NEXT: CompoundStmt + +#pragma acc data copyin(t) pcopyin(readonly: NTTP, u) present_or_copyin(u[0:t]) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: pcopyin clause : readonly + // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &' + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: present_or_copyin clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: NullStmt + +#pragma acc enter data copyin(t) pcopyin(readonly: NTTP, u) present_or_copyin(u[0:t]) + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: pcopyin clause : readonly + // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &' + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: present_or_copyin clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + + // Check the instantiated versions of the above. + // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation + // CHECK-NEXT: TemplateArgument decl + // CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: TemplateArgument type 'int *' + // CHECK-NEXT: PointerType{{.*}} 'int *' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used u 'int *' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: pcopyin clause : readonly + // CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: present_or_copyin clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: pcopyin clause : readonly + // CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: present_or_copyin clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' +} + +void Inst() { + static constexpr unsigned CEVar = 1; + int i; + TemplUses(i, &i); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-copyin-clause.c b/clang/test/SemaOpenACC/data-construct-copyin-clause.c new file mode 100644 index 0000000000000..370cc7000f8d8 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-copyin-clause.c @@ -0,0 +1,73 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +typedef struct IsComplete { + struct S { int A; } CompositeMember; + int ScalarMember; + float ArrayMember[5]; + void *PointerMember; +} Complete; +void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) { + int LocalInt; + short *LocalPointer; + float LocalArray[5]; + Complete LocalComposite; + // Check Appertainment: +#pragma acc data copyin(LocalInt) + ; +#pragma acc enter data copyin(LocalInt) + + // expected-warning@+1{{OpenACC clause name 'pcopyin' is a deprecated clause name and is now an alias for 'copyin'}} +#pragma acc data pcopyin(LocalInt) + ; + + // expected-warning@+1{{OpenACC clause name 'present_or_copyin' is a deprecated clause name and is now an alias for 'copyin'}} +#pragma acc data present_or_copyin(LocalInt) + ; + + // Valid cases: +#pragma acc data copyin(LocalInt, LocalPointer, LocalArray) + ; +#pragma acc data copyin(LocalArray[2:1]) + ; +#pragma acc data copyin(readonly:LocalArray[2:1]) + ; + +#pragma acc data copyin(LocalComposite.ScalarMember, LocalComposite.ScalarMember) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copyin(1 + IntParam) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copyin(+IntParam) + ; + + // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} +#pragma acc data copyin(PointerParam[2:]) + ; + + // expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} +#pragma acc data copyin(ArrayParam[2:5]) + ; + + // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copyin((float*)ArrayParam[2:5]) + ; + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copyin((float)ArrayParam[2]) + ; + // expected-error@+2{{invalid tag 'invalid' on 'copyin' clause}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copyin(invalid:(float)ArrayParam[2]) + ; + + // expected-error@+2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} + // expected-error@+1{{OpenACC 'copyin' clause is not valid on 'exit data' directive}} +#pragma acc exit data copyin(LocalInt) + // expected-error@+2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} + // expected-error@+1{{OpenACC 'pcopyin' clause is not valid on 'host_data' directive}} +#pragma acc host_data pcopyin(LocalInt) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-copyout-ast.cpp b/clang/test/SemaOpenACC/data-construct-copyout-ast.cpp new file mode 100644 index 0000000000000..38e6e7b476fe5 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-copyout-ast.cpp @@ -0,0 +1,137 @@ +// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +int Global; +short GlobalArray[5]; +void NormalUses(float *PointerParam) { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK: ParmVarDecl + // CHECK-NEXT: CompoundStmt + +#pragma acc data copyout(GlobalArray) pcopyout(zero:PointerParam[Global]) present_or_copyout(Global) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]' + // CHECK-NEXT: pcopyout clause : zero + // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: present_or_copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: NullStmt + +#pragma acc exit data copyout(GlobalArray) pcopyout(zero:PointerParam[Global]) present_or_copyout(Global) + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]' + // CHECK-NEXT: pcopyout clause : zero + // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: present_or_copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' +} + +template +void TemplUses(T t, U u) { + // CHECK-NEXT: FunctionTemplateDecl + // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U' + // CHECK-NEXT: CompoundStmt + +#pragma acc data copyout(t) pcopyout(zero: NTTP, u) present_or_copyout(u[0:t]) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: pcopyout clause : zero + // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &' + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: present_or_copyout clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: NullStmt + +#pragma acc exit data copyout(t) pcopyout(zero: NTTP, u) present_or_copyout(u[0:t]) + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: pcopyout clause : zero + // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &' + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: present_or_copyout clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + + // Check the instantiated versions of the above. + // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation + // CHECK-NEXT: TemplateArgument decl + // CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: TemplateArgument type 'int *' + // CHECK-NEXT: PointerType{{.*}} 'int *' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used u 'int *' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: pcopyout clause : zero + // CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: present_or_copyout clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: pcopyout clause : zero + // CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: present_or_copyout clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' +} + +void Inst() { + static constexpr unsigned CEVar = 1; + int i; + TemplUses(i, &i); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-copyout-clause.c b/clang/test/SemaOpenACC/data-construct-copyout-clause.c new file mode 100644 index 0000000000000..0f9d5f2ad5c83 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-copyout-clause.c @@ -0,0 +1,73 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +typedef struct IsComplete { + struct S { int A; } CompositeMember; + int ScalarMember; + float ArrayMember[5]; + void *PointerMember; +} Complete; +void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) { + int LocalInt; + short *LocalPointer; + float LocalArray[5]; + Complete LocalComposite; + // Check Appertainment: +#pragma acc data copyout(LocalInt) + ; +#pragma acc exit data copyout(LocalInt) + + // expected-warning@+1{{OpenACC clause name 'pcopyout' is a deprecated clause name and is now an alias for 'copyout'}} +#pragma acc data pcopyout(LocalInt) + ; + + // expected-warning@+1{{OpenACC clause name 'present_or_copyout' is a deprecated clause name and is now an alias for 'copyout'}} +#pragma acc data present_or_copyout(LocalInt) + ; + + // Valid cases: +#pragma acc data copyout(LocalInt, LocalPointer, LocalArray) + ; +#pragma acc data copyout(LocalArray[2:1]) + ; +#pragma acc data copyout(zero:LocalArray[2:1]) + ; + +#pragma acc data copyout(LocalComposite.ScalarMember, LocalComposite.ScalarMember) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copyout(1 + IntParam) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copyout(+IntParam) + ; + + // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} +#pragma acc data copyout(PointerParam[2:]) + ; + + // expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} +#pragma acc data copyout(ArrayParam[2:5]) + ; + + // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copyout((float*)ArrayParam[2:5]) + ; + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copyout((float)ArrayParam[2]) + ; + // expected-error@+2{{invalid tag 'invalid' on 'copyout' clause}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data copyout(invalid:(float)ArrayParam[2]) + ; + + // expected-error@+2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} + // expected-error@+1{{OpenACC 'copyout' clause is not valid on 'enter data' directive}} +#pragma acc enter data copyout(LocalInt) + // expected-error@+2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} + // expected-error@+1{{OpenACC 'pcopyout' clause is not valid on 'host_data' directive}} +#pragma acc host_data pcopyout(LocalInt) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-create-ast.cpp b/clang/test/SemaOpenACC/data-construct-create-ast.cpp new file mode 100644 index 0000000000000..623d44aac43f9 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-create-ast.cpp @@ -0,0 +1,137 @@ +// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -Wno-openacc-deprecated-clause-alias -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +int Global; +short GlobalArray[5]; +void NormalUses(float *PointerParam) { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK: ParmVarDecl + // CHECK-NEXT: CompoundStmt + +#pragma acc data create(GlobalArray) pcreate(zero:PointerParam[Global]) present_or_create(Global) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: create clause + // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]' + // CHECK-NEXT: pcreate clause : zero + // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: present_or_create clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: NullStmt + +#pragma acc enter data create(GlobalArray) pcreate(zero:PointerParam[Global]) present_or_create(Global) + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data + // CHECK-NEXT: create clause + // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]' + // CHECK-NEXT: pcreate clause : zero + // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: present_or_create clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' +} + +template +void TemplUses(T t, U u) { + // CHECK-NEXT: FunctionTemplateDecl + // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U' + // CHECK-NEXT: CompoundStmt + +#pragma acc data create(t) pcreate(zero: NTTP, u) present_or_create(u[0:t]) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: create clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: pcreate clause : zero + // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &' + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: present_or_create clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: NullStmt + +#pragma acc enter data create(t) pcreate(zero: NTTP, u) present_or_create(u[0:t]) + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data + // CHECK-NEXT: create clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: pcreate clause : zero + // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &' + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: present_or_create clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + + // Check the instantiated versions of the above. + // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation + // CHECK-NEXT: TemplateArgument decl + // CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: TemplateArgument type 'int *' + // CHECK-NEXT: PointerType{{.*}} 'int *' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used u 'int *' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: create clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: pcreate clause : zero + // CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: present_or_create clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}} enter data + // CHECK-NEXT: create clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: pcreate clause : zero + // CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: present_or_create clause + // CHECK-NEXT: ArraySectionExpr + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int *' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: IntegerLiteral{{.*}} 'int' 0 + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' +} + +void Inst() { + static constexpr unsigned CEVar = 1; + int i; + TemplUses(i, &i); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-create-clause.c b/clang/test/SemaOpenACC/data-construct-create-clause.c new file mode 100644 index 0000000000000..4972bdca4b85d --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-create-clause.c @@ -0,0 +1,73 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +typedef struct IsComplete { + struct S { int A; } CompositeMember; + int ScalarMember; + float ArrayMember[5]; + void *PointerMember; +} Complete; +void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) { + int LocalInt; + short *LocalPointer; + float LocalArray[5]; + Complete LocalComposite; + // Check Appertainment: +#pragma acc data create(LocalInt) + ; +#pragma acc enter data create(LocalInt) + + // expected-warning@+1{{OpenACC clause name 'pcreate' is a deprecated clause name and is now an alias for 'create'}} +#pragma acc data pcreate(LocalInt) + ; + + // expected-warning@+1{{OpenACC clause name 'present_or_create' is a deprecated clause name and is now an alias for 'create'}} +#pragma acc data present_or_create(LocalInt) + ; + + // Valid cases: +#pragma acc data create(LocalInt, LocalPointer, LocalArray) + ; +#pragma acc data create(LocalArray[2:1]) + ; +#pragma acc data create(zero:LocalArray[2:1]) + ; + +#pragma acc data create(LocalComposite.ScalarMember, LocalComposite.ScalarMember) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data create(1 + IntParam) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data create(+IntParam) + ; + + // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} +#pragma acc data create(PointerParam[2:]) + ; + + // expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} +#pragma acc data create(ArrayParam[2:5]) + ; + + // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data create((float*)ArrayParam[2:5]) + ; + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data create((float)ArrayParam[2]) + ; + // expected-error@+2{{invalid tag 'invalid' on 'create' clause}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data create(invalid:(float)ArrayParam[2]) + ; + + // expected-error@+2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} + // expected-error@+1{{OpenACC 'create' clause is not valid on 'exit data' directive}} +#pragma acc exit data create(LocalInt) + // expected-error@+2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} + // expected-error@+1{{OpenACC 'pcreate' clause is not valid on 'host_data' directive}} +#pragma acc host_data pcreate(LocalInt) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-default-ast.cpp b/clang/test/SemaOpenACC/data-construct-default-ast.cpp new file mode 100644 index 0000000000000..ef9b1348c6709 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-default-ast.cpp @@ -0,0 +1,68 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER +void NormalFunc() { + // CHECK-LABEL: NormalFunc + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: OpenACCDataConstruct {{.*}}data + // CHECK-NEXT: default(none) +#pragma acc data default(none) + // CHECK: OpenACCDataConstruct {{.*}}data + // CHECK-NEXT: default(present) +#pragma acc data default(present) + ; +} +template +void TemplFunc() { +#pragma acc data default(none) + for (unsigned i = 0; i < 5; ++i) { + typename T::type I; + } + +#pragma acc data default(present) + for (unsigned i = 0; i < 5; ++i) { + typename T::type I; + } + + // CHECK-LABEL: FunctionTemplateDecl {{.*}}TemplFunc + // CHECK-NEXT: TemplateTypeParmDecl + + // Template Pattern: + // CHECK-NEXT: FunctionDecl + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: OpenACCDataConstruct {{.*}}data + // CHECK-NEXT: default(none) + // CHECK: VarDecl{{.*}} I 'typename T::type' + + // CHECK-NEXT: OpenACCDataConstruct {{.*}}data + // CHECK-NEXT: default(present) + // CHECK: VarDecl{{.*}} I 'typename T::type' + + // Check instantiation. + // CHECK-LABEL: FunctionDecl{{.*}} used TemplFunc 'void ()' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'S' + // CHECK-NEXT: RecordType + // CHECK-NEXT: CXXRecord + // CHECK-NEXT: CompoundStmt + // CHECK-NEXT: OpenACCDataConstruct {{.*}}data + // CHECK-NEXT: default(none) + // CHECK: VarDecl{{.*}} I 'typename S::type':'int' + // CHECK-NEXT: OpenACCDataConstruct {{.*}}data + // CHECK-NEXT: default(present) + // CHECK: VarDecl{{.*}} I 'typename S::type':'int' + +} +struct S { + using type = int; +}; + +void use() { + TemplFunc(); +} + +#endif diff --git a/clang/test/SemaOpenACC/data-construct-default-clause.c b/clang/test/SemaOpenACC/data-construct-default-clause.c new file mode 100644 index 0000000000000..150d3ec22dcda --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-default-clause.c @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +void use() { + // expected-error@+2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} + // expected-error@+1{{invalid value for 'default' clause; expected 'present' or 'none'}} +#pragma acc data default(garbage) + ; +#pragma acc data default(present) + ; +#pragma acc data default(none) + ; + // expected-error@+2{{OpenACC 'default' clause cannot appear more than once on a 'data' directive}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) default(present) + ; + // expected-error@+2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} + // expected-error@+1{{OpenACC 'default' clause is not valid on 'enter data' directive}} +#pragma acc enter data default(present) + ; + // expected-error@+2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} + // expected-error@+1{{OpenACC 'default' clause is not valid on 'exit data' directive}} +#pragma acc exit data default(none) + ; + // expected-error@+2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} + // expected-error@+1{{OpenACC 'default' clause is not valid on 'host_data' directive}} +#pragma acc host_data default(present) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-delete-ast.cpp b/clang/test/SemaOpenACC/data-construct-delete-ast.cpp new file mode 100644 index 0000000000000..b61fdc900928d --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-delete-ast.cpp @@ -0,0 +1,58 @@ + +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +int Global; +short GlobalArray[5]; +void NormalUses(float *PointerParam) { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK: ParmVarDecl + // CHECK-NEXT: CompoundStmt + +#pragma acc exit data delete(GlobalArray, PointerParam[Global]) + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data + // CHECK-NEXT: delete clause + // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]' + // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' +} + +template +void TemplUses(T t) { + // CHECK-NEXT: FunctionTemplateDecl + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 0 T + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T' + // CHECK-NEXT: CompoundStmt + +#pragma acc exit data delete(t) + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data + // CHECK-NEXT: delete clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + + // Check the instantiated versions of the above. + // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int)' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data + // CHECK-NEXT: delete clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' +} + +void Inst() { + int i; + TemplUses(i); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-delete-clause.c b/clang/test/SemaOpenACC/data-construct-delete-clause.c new file mode 100644 index 0000000000000..05093dbc4e01b --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-delete-clause.c @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +typedef struct IsComplete { + struct S { int A; } CompositeMember; + int ScalarMember; + float ArrayMember[5]; + void *PointerMember; +} Complete; +void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) { + int LocalInt; + short *LocalPointer; + float LocalArray[5]; + Complete LocalComposite; + // Check Appertainment: +#pragma acc exit data delete(LocalInt) + + // Valid cases: +#pragma acc exit data delete(LocalInt, LocalPointer, LocalArray) +#pragma acc exit data delete(LocalArray[2:1]) +#pragma acc exit data delete(LocalComposite.ScalarMember, LocalComposite.ScalarMember) + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc exit data delete(1 + IntParam) + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc exit data delete(+IntParam) + + // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} +#pragma acc exit data delete(PointerParam[2:]) + + // expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} +#pragma acc exit data delete(ArrayParam[2:5]) + + // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc exit data delete((float*)ArrayParam[2:5]) + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc exit data delete((float)ArrayParam[2]) + + // expected-error@+2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'data' directive}} +#pragma acc data delete(LocalInt) + ; + // expected-error@+2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'enter data' directive}} +#pragma acc enter data delete(LocalInt) + // expected-error@+2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'host_data' directive}} +#pragma acc host_data delete(LocalInt) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-detach-ast.cpp b/clang/test/SemaOpenACC/data-construct-detach-ast.cpp new file mode 100644 index 0000000000000..d5096cdc868d0 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-detach-ast.cpp @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +int Global; +short GlobalArray[5]; + +void NormalUses(float *PointerParam) { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK: ParmVarDecl + // CHECK-NEXT: CompoundStmt + +#pragma acc exit data copyout(Global) detach(PointerParam) + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Global' 'int' + // CHECK-NEXT: detach clause + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}} 'PointerParam' 'float *' +} + +template +void TemplUses(T *t) { + // CHECK-NEXT: FunctionTemplateDecl + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 0 T + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T *)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T *' + // CHECK-NEXT: CompoundStmt + +#pragma acc exit data copyout(Global) detach(t) + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Global' 'int' + // CHECK-NEXT: detach clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T *' lvalue ParmVar{{.*}} 't' 'T *' + + + // Check the instantiated versions of the above. + // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int *)' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int *' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}} exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Global' 'int' + // CHECK-NEXT: detach clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 't' 'int *' + +} + +void Inst() { + int i; + TemplUses(&i); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-detach-clause.c b/clang/test/SemaOpenACC/data-construct-detach-clause.c new file mode 100644 index 0000000000000..edcc80ac36236 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-detach-clause.c @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +struct S { + int IntMem; + int *PtrMem; +}; + +void uses() { + int LocalInt; + int *LocalPtr; + int Array[5]; + int *PtrArray[5]; + struct S s; + + // expected-error@+1{{expected pointer in 'detach' clause, type is 'int'}} +#pragma acc exit data copyout(LocalInt) detach(LocalInt) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc exit data copyout(LocalInt) detach(&LocalInt) + ; + + + // expected-error@+1{{expected pointer in 'detach' clause, type is 'int[5]'}} +#pragma acc exit data copyout(LocalInt) detach(Array) + + // expected-error@+1{{expected pointer in 'detach' clause, type is 'int'}} +#pragma acc exit data copyout(LocalInt) detach(Array[0]) + ; + + // expected-error@+2{{OpenACC sub-array is not allowed here}} + // expected-note@+1{{expected variable of pointer type}} +#pragma acc exit data copyout(LocalInt) detach(Array[0:1]) + ; + + // expected-error@+1{{expected pointer in 'detach' clause, type is 'int *[5]'}} +#pragma acc exit data copyout(LocalInt) detach(PtrArray) + ; + +#pragma acc exit data copyout(LocalInt) detach(PtrArray[0]) + ; + + // expected-error@+2{{OpenACC sub-array is not allowed here}} + // expected-note@+1{{expected variable of pointer type}} +#pragma acc exit data copyout(LocalInt) detach(PtrArray[0:1]) + ; + + // expected-error@+1{{expected pointer in 'detach' clause, type is 'struct S'}} +#pragma acc exit data copyout(LocalInt) detach(s) + ; + + // expected-error@+1{{expected pointer in 'detach' clause, type is 'int'}} +#pragma acc exit data copyout(LocalInt) detach(s.IntMem) + ; + +#pragma acc exit data copyout(LocalInt) detach(s.PtrMem) + ; + + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'data' directive}} +#pragma acc data copyin(LocalInt) detach(PtrArray[0]) + ; + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'enter data' directive}} +#pragma acc enter data copyin(LocalInt) detach(PtrArray[0]) + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'host_data' directive}} +#pragma acc host_data use_device(LocalInt) detach(PtrArray[0]) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-device_type-ast.cpp b/clang/test/SemaOpenACC/data-construct-device_type-ast.cpp new file mode 100644 index 0000000000000..1f497bb7afcc4 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-device_type-ast.cpp @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s +#ifndef PCH_HELPER +#define PCH_HELPER + +template +void TemplUses() { + // CHECK: FunctionTemplateDecl{{.*}}TemplUses + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}T + // CHECK-NEXT: FunctionDecl{{.*}}TemplUses + // CHECK-NEXT: CompoundStmt + +#pragma acc data default(none) device_type(T) dtype(T) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: default(none) + // CHECK-NEXT: device_type(T) + // CHECK-NEXT: dtype(T) + // CHECK-NEXT: NullStmt + + // Instantiations + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void ()' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: CompoundStmt + + // Argument to 'device-type' is just an identifier, so we don't transform it. + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: default(none) + // CHECK-NEXT: device_type(T) + // CHECK-NEXT: dtype(T) + // CHECK-NEXT: NullStmt +} +void Inst() { + TemplUses(); +} + +#endif // PCH_HELPER diff --git a/clang/test/SemaOpenACC/data-construct-device_type-clause.c b/clang/test/SemaOpenACC/data-construct-device_type-clause.c new file mode 100644 index 0000000000000..a467287b93e0c --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-device_type-clause.c @@ -0,0 +1,55 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +void uses() { + int Var; +#pragma acc data default(none) device_type(foo) async + ; +#pragma acc data default(none) device_type(foo) wait + ; +#pragma acc data default(none) device_type(foo) dtype(false) + ; +#pragma acc data default(none) dtype(foo) device_type(false) + ; + + // expected-error@+2{{OpenACC clause 'if' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(foo) if(1) + ; + // expected-error@+2{{OpenACC clause 'copy' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(foo) copy(Var) + ; + // expected-error@+2{{OpenACC clause 'copyin' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(foo) copyin(Var) + ; + // expected-error@+2{{OpenACC clause 'copyout' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(foo) copyout(Var) + ; + // expected-error@+2{{OpenACC clause 'create' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(foo) create(Var) + ; + // expected-error@+2{{OpenACC clause 'no_create' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(foo) no_create(Var) + ; + // expected-error@+2{{OpenACC clause 'present' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(foo) present(Var) + ; + // expected-error@+2{{OpenACC clause 'deviceptr' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(foo) deviceptr(Var) + ; + // expected-error@+2{{OpenACC clause 'attach' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(foo) attach(Var) + ; + // expected-error@+3{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} + // expected-error@+2{{OpenACC clause 'default' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data device_type(foo) default(none) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-deviceptr-ast.cpp b/clang/test/SemaOpenACC/data-construct-deviceptr-ast.cpp new file mode 100644 index 0000000000000..a4ac289ab4827 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-deviceptr-ast.cpp @@ -0,0 +1,66 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +int Global; +short GlobalArray[5]; + +void NormalUses(float *PointerParam) { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK: ParmVarDecl + // CHECK-NEXT: CompoundStmt + +#pragma acc data default(present) deviceptr(PointerParam) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: default(present) + // CHECK-NEXT: deviceptr clause + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}} 'PointerParam' 'float *' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +} + +template +void TemplUses(T *t) { + // CHECK-NEXT: FunctionTemplateDecl + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 0 T + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T *)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T *' + // CHECK-NEXT: CompoundStmt + +#pragma acc data default(present) deviceptr(t) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: default(present) + // CHECK-NEXT: deviceptr clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T *' lvalue ParmVar{{.*}} 't' 'T *' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + + // Check the instantiated versions of the above. + // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int *)' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int *' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: default(present) + // CHECK-NEXT: deviceptr clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 't' 'int *' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +} + +void Inst() { + int i; + TemplUses(&i); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-deviceptr-clause.c b/clang/test/SemaOpenACC/data-construct-deviceptr-clause.c new file mode 100644 index 0000000000000..70ccd3b7aec95 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-deviceptr-clause.c @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +struct S { + int IntMem; + int *PtrMem; +}; + +void uses() { + int LocalInt; + int *LocalPtr; + int Array[5]; + int *PtrArray[5]; + struct S s; + + // expected-error@+1{{expected pointer in 'deviceptr' clause, type is 'int'}} +#pragma acc data default(none) deviceptr(LocalInt) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data default(none) deviceptr(&LocalInt) + ; + + + // expected-error@+1{{expected pointer in 'deviceptr' clause, type is 'int[5]'}} +#pragma acc data default(none) deviceptr(Array) + ; + + // expected-error@+1{{expected pointer in 'deviceptr' clause, type is 'int'}} +#pragma acc data default(none) deviceptr(Array[0]) + ; + + // expected-error@+2{{OpenACC sub-array is not allowed here}} + // expected-note@+1{{expected variable of pointer type}} +#pragma acc data default(none) deviceptr(Array[0:1]) + ; + + // expected-error@+1{{expected pointer in 'deviceptr' clause, type is 'int *[5]'}} +#pragma acc data default(none) deviceptr(PtrArray) + ; + +#pragma acc data default(none) deviceptr(PtrArray[0]) + ; + + // expected-error@+2{{OpenACC sub-array is not allowed here}} + // expected-note@+1{{expected variable of pointer type}} +#pragma acc data default(none) deviceptr(PtrArray[0:1]) + ; + + // expected-error@+1{{expected pointer in 'deviceptr' clause, type is 'struct S'}} +#pragma acc data default(none) deviceptr(s) + ; + + // expected-error@+1{{expected pointer in 'deviceptr' clause, type is 'int'}} +#pragma acc data default(none) deviceptr(s.IntMem) + ; + +#pragma acc data default(none) deviceptr(s.PtrMem) + ; + + // expected-error@+1{{OpenACC 'deviceptr' clause is not valid on 'enter data' directive}} +#pragma acc enter data copyin(LocalInt) deviceptr(LocalInt) + // expected-error@+1{{OpenACC 'deviceptr' clause is not valid on 'exit data' directive}} +#pragma acc exit data copyout(LocalInt) deviceptr(LocalInt) + // expected-error@+1{{OpenACC 'deviceptr' clause is not valid on 'host_data' directive}} +#pragma acc host_data use_device(LocalInt) deviceptr(LocalInt) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-finalize-ast.cpp b/clang/test/SemaOpenACC/data-construct-finalize-ast.cpp new file mode 100644 index 0000000000000..0dc6605cc6042 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-finalize-ast.cpp @@ -0,0 +1,60 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s +#ifndef PCH_HELPER +#define PCH_HELPER + +void Uses() { + // CHECK: FunctionDecl{{.*}}Uses + // CHECK-NEXT: CompoundStmt + + int I; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + +#pragma acc exit data copyout(I) finalize + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'int' + // CHECK-NEXT: finalize clause +} + +template +void TemplUses() { + // CHECK: FunctionTemplateDecl{{.*}}TemplUses + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}T + // CHECK-NEXT: FunctionDecl{{.*}}TemplUses + // CHECK-NEXT: CompoundStmt + + T I; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + +#pragma acc exit data copyout(I) finalize + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'T' + // CHECK-NEXT: finalize clause + + // Instantiations + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void ()' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'int' + // CHECK-NEXT: finalize clause +} +void Inst() { + TemplUses(); +} + + +#endif // PCH_HELPER diff --git a/clang/test/SemaOpenACC/data-construct-finalize-clause.c b/clang/test/SemaOpenACC/data-construct-finalize-clause.c new file mode 100644 index 0000000000000..252b26708cd81 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-finalize-clause.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +void Test() { + int I; + + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'data' directive}} +#pragma acc data copyin(I) finalize + ; + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'enter data' directive}} +#pragma acc enter data copyin(I) finalize + ; + + // finalize is valid only on exit data, otherwise has no other rules. +#pragma acc exit data copyout(I) finalize + ; + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'host_data' directive}} +#pragma acc host_data use_device(I) finalize + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-if-ast.cpp b/clang/test/SemaOpenACC/data-construct-if-ast.cpp new file mode 100644 index 0000000000000..9ceee4e1c0749 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-if-ast.cpp @@ -0,0 +1,143 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER +void NormalFunc(int j, float f) { + // CHECK: FunctionDecl{{.*}}NormalFunc + // CHECK-NEXT: ParmVarDecl + // CHECK-NEXT: ParmVarDecl + // CHECK-NEXT: CompoundStmt +#pragma acc data if( j < f) default(none) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: if clause + // CHECK-NEXT: BinaryOperator{{.*}} 'bool' '<' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}} 'int' lvalue ParmVar{{.*}} 'j' 'int' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float' + // CHECK-NEXT: DeclRefExpr{{.*}} 'float' lvalue ParmVar{{.*}} 'f' 'float' + // CHECK-NEXT: default(none) + // CHECK-NEXT: NullStmt + +} + +int Global; + +template +void TemplFunc() { + // CHECK: FunctionTemplateDecl{{.*}}TemplFunc + // CHECK-NEXT: TemplateTypeParmDecl + + // Match the prototype: + // CHECK-NEXT: FunctionDecl{{.*}}TemplFunc + // CHECK-NEXT: CompoundStmt + +#pragma acc data default(none) if(T::SomeFloat < typename T::IntTy{}) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: default(none) + // CHECK-NEXT: if clause + // CHECK-NEXT: BinaryOperator{{.*}} '' '<' + // CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '' lvalue + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'T' + // CHECK-NEXT: CXXUnresolvedConstructExpr{{.*}} 'typename T::IntTy' 'typename T::IntTy' + // CHECK-NEXT: InitListExpr{{.*}} 'void' + // CHECK-NEXT: NullStmt + +#pragma acc enter data copyin(Global) if(typename T::IntTy{}) + ; + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}}enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Global' 'int' + // CHECK-NEXT: if clause + // CHECK-NEXT: CXXUnresolvedConstructExpr{{.*}} 'typename T::IntTy' 'typename T::IntTy' + // CHECK-NEXT: InitListExpr{{.*}} 'void' + // CHECK-NEXT: NullStmt + +#pragma acc exit data copyout(Global) if(T::SomeFloat) + ; + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Global' 'int' + // CHECK-NEXT: if clause + // CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '' lvalue + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'T' + // CHECK-NEXT: NullStmt + +#pragma acc host_data use_device(Global) if(T::BC) + ; + // CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data + // CHECK-NEXT: use_device clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Global' 'int' + // CHECK-NEXT: if clause + // CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '' lvalue + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'T' + // CHECK-NEXT: NullStmt + + // Match the instantiation: + // CHECK: FunctionDecl{{.*}}TemplFunc{{.*}}implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'InstTy' + // CHECK-NEXT: RecordType{{.*}} 'InstTy' + // CHECK-NEXT: CXXRecord{{.*}} 'InstTy' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: default(none) + // CHECK-NEXT: if clause + // CHECK-NEXT: BinaryOperator{{.*}} 'bool' '<' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float' + // CHECK-NEXT: DeclRefExpr{{.*}} 'const float' lvalue Var{{.*}} 'SomeFloat' 'const float' + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float' + // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename struct InstTy::IntTy + // CHECK-NEXT: InitListExpr {{.*}}'typename InstTy::IntTy':'int' + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCEnterDataConstruct{{.*}}enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Global' 'int' + // CHECK-NEXT: if clause + // CHECK-NEXT: ImplicitCastExpr{{.*}}'bool' + // CHECK-NEXT: CXXFunctionalCastExpr{{.*}}'typename InstTy::IntTy':'int' functional cast to typename struct InstTy::IntTy + // CHECK-NEXT: InitListExpr {{.*}}'typename InstTy::IntTy':'int' + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Global' 'int' + // CHECK-NEXT: if clause + // CHECK-NEXT: ImplicitCastExpr{{.*}}'bool' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'float' + // CHECK-NEXT: DeclRefExpr{{.*}} 'const float' lvalue Var{{.*}} 'SomeFloat' 'const float' + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy' + // CHECK-NEXT: NullStmt + + // CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data + // CHECK-NEXT: use_device clause + // CHECK-NEXT: DeclRefExpr{{.*}}'Global' 'int' + // CHECK-NEXT: if clause + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'bool' + // CHECK-NEXT: CXXMemberCallExpr{{.*}} 'bool' + // CHECK-NEXT: MemberExpr{{.*}} .operator bool + // CHECK-NEXT: DeclRefExpr{{.*}} 'const BoolConversion' lvalue Var{{.*}} 'BC' 'const BoolConversion' + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'InstTy' + // CHECK-NEXT: NullStmt + +} + +struct BoolConversion{ operator bool() const;}; +struct InstTy { + using IntTy = int; + static constexpr float SomeFloat = 5.0; + static constexpr BoolConversion BC; +}; + +void Instantiate() { + TemplFunc(); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-if-clause.c b/clang/test/SemaOpenACC/data-construct-if-clause.c new file mode 100644 index 0000000000000..f22452d2c34a4 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-if-clause.c @@ -0,0 +1,29 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +void Foo() { + int Var; +#pragma acc data default(present) if(1) + ; + // expected-error@+2{{OpenACC 'if' clause cannot appear more than once on a 'data' directive}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(present) if(1) if (2) + ; + +#pragma acc enter data copyin(Var) if(1) + + // expected-error@+2{{OpenACC 'if' clause cannot appear more than once on a 'enter data' directive}} + // expected-note@+1{{previous clause is here}} +#pragma acc enter data copyin(Var) if(1) if (2) + +#pragma acc exit data copyout(Var) if(1) + // expected-error@+2{{OpenACC 'if' clause cannot appear more than once on a 'exit data' directive}} + // expected-note@+1{{previous clause is here}} +#pragma acc exit data copyout(Var) if(1) if (2) + +#pragma acc host_data use_device(Var) if(1) + ; + // expected-error@+2{{OpenACC 'if' clause cannot appear more than once on a 'host_data' directive}} + // expected-note@+1{{previous clause is here}} +#pragma acc host_data use_device(Var) if(1) if (2) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-if_present-ast.cpp b/clang/test/SemaOpenACC/data-construct-if_present-ast.cpp new file mode 100644 index 0000000000000..8dab6bcce58d9 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-if_present-ast.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s +#ifndef PCH_HELPER +#define PCH_HELPER + +void Uses() { + // CHECK: FunctionDecl{{.*}}Uses + // CHECK-NEXT: CompoundStmt + + int I; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + +#pragma acc host_data use_device(I) if_present + ; + // CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data + // CHECK-NEXT: use_device clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'int' + // CHECK-NEXT: if_present clause + // CHECK-NEXT: NullStmt +} + +template +void TemplUses() { + // CHECK: FunctionTemplateDecl{{.*}}TemplUses + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}T + // CHECK-NEXT: FunctionDecl{{.*}}TemplUses + // CHECK-NEXT: CompoundStmt + + T I; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + +#pragma acc host_data use_device(I) if_present + ; + // CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data + // CHECK-NEXT: use_device clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'T' + // CHECK-NEXT: if_present clause + // CHECK-NEXT: NullStmt + + // Instantiations + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void ()' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + + // CHECK-NEXT: OpenACCHostDataConstruct{{.*}}host_data + // CHECK-NEXT: use_device clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'int' + // CHECK-NEXT: if_present clause + // CHECK-NEXT: NullStmt +} +void Inst() { + TemplUses(); +} + + +#endif // PCH_HELPER diff --git a/clang/test/SemaOpenACC/data-construct-if_present-clause.c b/clang/test/SemaOpenACC/data-construct-if_present-clause.c new file mode 100644 index 0000000000000..b1290cdccca5f --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-if_present-clause.c @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +void Test() { + int I; + + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'data' directive}} +#pragma acc data copyin(I) if_present + ; + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'enter data' directive}} +#pragma acc enter data copyin(I) if_present + ; + + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'exit data' directive}} +#pragma acc exit data copyout(I) if_present + ; +#pragma acc host_data use_device(I) if_present + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-no_create-ast.cpp b/clang/test/SemaOpenACC/data-construct-no_create-ast.cpp new file mode 100644 index 0000000000000..9a0465d455942 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-no_create-ast.cpp @@ -0,0 +1,82 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +int Global; +short GlobalArray[5]; +void NormalUses(float *PointerParam) { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK: ParmVarDecl + // CHECK-NEXT: CompoundStmt + +#pragma acc data no_create(GlobalArray, PointerParam[Global]) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: no_create clause + // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]' + // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: NullStmt +} + +template +void TemplUses(T t, U u) { + // CHECK-NEXT: FunctionTemplateDecl + // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 2 U + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T, U)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U' + // CHECK-NEXT: CompoundStmt + + +#pragma acc data no_create(t) present(NTTP, u) + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: no_create clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: present clause + // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &' + // CHECK-NEXT: DeclRefExpr{{.*}}'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: NullStmt + + // Check the instantiated versions of the above. + // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int, int *)' implicit_instantiation + // CHECK-NEXT: TemplateArgument decl + // CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: TemplateArgument type 'int *' + // CHECK-NEXT: PointerType{{.*}} 'int *' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} u 'int *' + // CHECK-NEXT: CompoundStmt + +// #pragma acc data no_create(t) present(NTTP, u) + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: no_create clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: present clause + // CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int *' lvalue ParmVar{{.*}} 'u' 'int *' + // CHECK-NEXT: NullStmt +} + +void Inst() { + static constexpr unsigned CEVar = 1; + int i; + TemplUses(i, &i); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-no_create-clause.c b/clang/test/SemaOpenACC/data-construct-no_create-clause.c new file mode 100644 index 0000000000000..0eb459eb0009a --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-no_create-clause.c @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +typedef struct IsComplete { + struct S { int A; } CompositeMember; + int ScalarMember; + float ArrayMember[5]; + void *PointerMember; +} Complete; +void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) { + int LocalInt; + short *LocalPointer; + float LocalArray[5]; + Complete LocalComposite; + // Check Appertainment: +#pragma acc data no_create(LocalInt) + ; + + // Valid cases: +#pragma acc data no_create(LocalInt, LocalPointer, LocalArray) + ; +#pragma acc data no_create(LocalArray[2:1]) + ; + +#pragma acc data no_create(LocalComposite.ScalarMember, LocalComposite.ScalarMember) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data no_create(1 + IntParam) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data no_create(+IntParam) + ; + + // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} +#pragma acc data no_create(PointerParam[2:]) + ; + + // expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} +#pragma acc data no_create(ArrayParam[2:5]) + ; + + // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data no_create((float*)ArrayParam[2:5]) + ; + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data no_create((float)ArrayParam[2]) + ; + + // expected-error@+2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} + // expected-error@+1{{OpenACC 'no_create' clause is not valid on 'exit data' directive}} +#pragma acc exit data no_create(LocalInt) + // expected-error@+2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} + // expected-error@+1{{OpenACC 'no_create' clause is not valid on 'enter data' directive}} +#pragma acc enter data no_create(LocalInt) + // expected-error@+2{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} + // expected-error@+1{{OpenACC 'no_create' clause is not valid on 'host_data' directive}} +#pragma acc host_data no_create(LocalInt) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-present-ast.cpp b/clang/test/SemaOpenACC/data-construct-present-ast.cpp new file mode 100644 index 0000000000000..2a2d81f3f2483 --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-present-ast.cpp @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +int Global; +short GlobalArray[5]; + +void NormalUses(float *PointerParam) { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK: ParmVarDecl + // CHECK-NEXT: CompoundStmt + +#pragma acc data default(none) present(GlobalArray, PointerParam[Global]) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: default(none) + // CHECK-NEXT: present clause + // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]' + // CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'float *' + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue Var{{.*}}'Global' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt +} + +template +void TemplUses(T t) { + // CHECK-NEXT: FunctionTemplateDecl + // CHECK-NEXT: NonTypeTemplateParmDecl {{.*}}referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 1 T + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T' + // CHECK-NEXT: CompoundStmt + +#pragma acc data default(none) present(NTTP, t) + for(int i = 0; i < 5; ++i); + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: default(none) + // CHECK-NEXT: present clause + // CHECK-NEXT: DeclRefExpr{{.*}}'auto' lvalue NonTypeTemplateParm{{.*}} 'NTTP' 'auto &' + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + + + // Check the instantiated versions of the above. + // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int)' implicit_instantiation + // CHECK-NEXT: TemplateArgument decl + // CHECK-NEXT: Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int' + // CHECK-NEXT: CompoundStmt + +// #pragma acc parallel seq present(NTTP, t) + // CHECK-NEXT: OpenACCDataConstruct{{.*}} data + // CHECK-NEXT: default(none) + // CHECK-NEXT: present clause + // CHECK-NEXT: SubstNonTypeTemplateParmExpr{{.*}}'const unsigned int' lvalue + // CHECK-NEXT: NonTypeTemplateParmDecl{{.*}} referenced 'auto &' depth 0 index 0 NTTP + // CHECK-NEXT: DeclRefExpr{{.*}}'const unsigned int' lvalue Var{{.*}} 'CEVar' 'const unsigned int' + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: ForStmt + // CHECK: NullStmt + +} + +void Inst() { + static constexpr unsigned CEVar = 1; + TemplUses(5); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-present-clause.c b/clang/test/SemaOpenACC/data-construct-present-clause.c new file mode 100644 index 0000000000000..b889230d177cd --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-present-clause.c @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +typedef struct IsComplete { + struct S { int A; } CompositeMember; + int ScalarMember; + float ArrayMember[5]; + void *PointerMember; +} Complete; +void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) { + int LocalInt; + short *LocalPointer; + float LocalArray[5]; + Complete LocalComposite; + // Check Appertainment: +#pragma acc data default(none) present(LocalInt) + ; + + // Valid cases: +#pragma acc data default(none) present(LocalInt, LocalPointer, LocalArray) + ; +#pragma acc data default(none) present(LocalArray[2:1]) + ; + +#pragma acc data default(none) present(LocalComposite.ScalarMember, LocalComposite.ScalarMember) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data default(none) present(1 + IntParam) + ; + + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data default(none) present(+IntParam) + ; + + // expected-error@+1{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} +#pragma acc data default(none) present(PointerParam[2:]) + ; + + // expected-error@+1{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} +#pragma acc data default(none) present(ArrayParam[2:5]) + ; + + // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data default(none) present((float*)ArrayParam[2:5]) + ; + // expected-error@+1{{OpenACC variable is not a valid variable name, sub-array, array element, member of a composite variable, or composite variable member}} +#pragma acc data default(none) present((float)ArrayParam[2]) + ; + + // expected-error@+1{{OpenACC 'present' clause is not valid on 'enter data' directive}} +#pragma acc enter data copyin(LocalInt) present(LocalInt) + // expected-error@+1{{OpenACC 'present' clause is not valid on 'exit data' directive}} +#pragma acc exit data copyout(LocalInt) present(LocalInt) + // expected-error@+1{{OpenACC 'present' clause is not valid on 'host_data' directive}} +#pragma acc host_data use_device(LocalInt) present(LocalInt) + ; +} diff --git a/clang/test/SemaOpenACC/data-construct-use_device-ast.cpp b/clang/test/SemaOpenACC/data-construct-use_device-ast.cpp new file mode 100644 index 0000000000000..b8cc30e14671f --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-use_device-ast.cpp @@ -0,0 +1,58 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +int Global; +short GlobalArray[5]; +void NormalUses(float *PointerParam) { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK: ParmVarDecl + // CHECK-NEXT: CompoundStmt + +#pragma acc host_data use_device(GlobalArray, PointerParam) + ; + // CHECK-NEXT: OpenACCHostDataConstruct{{.*}} host_data + // CHECK-NEXT: use_device clause + // CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]' + // CHECK-NEXT: DeclRefExpr{{.*}}'float *' lvalue ParmVar{{.*}}'PointerParam' 'float *' + // CHECK-NEXT: NullStmt +} + +template +void TemplUses(T t) { + // CHECK-NEXT: FunctionTemplateDecl + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 0 T + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (T)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced t 'T' + // CHECK-NEXT: CompoundStmt + +#pragma acc host_data use_device(t) + ; + // CHECK-NEXT: OpenACCHostDataConstruct{{.*}} host_data + // CHECK-NEXT: use_device clause + // CHECK-NEXT: DeclRefExpr{{.*}}'T' lvalue ParmVar{{.*}} 't' 'T' + // CHECK-NEXT: NullStmt + + // Check the instantiated versions of the above. + // CHECK-NEXT: FunctionDecl{{.*}} used TemplUses 'void (int)' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'int' + // CHECK-NEXT: BuiltinType{{.*}} 'int' + // CHECK-NEXT: ParmVarDecl{{.*}} used t 'int' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: OpenACCHostDataConstruct{{.*}} host_data + // CHECK-NEXT: use_device clause + // CHECK-NEXT: DeclRefExpr{{.*}}'int' lvalue ParmVar{{.*}} 't' 'int' + // CHECK-NEXT: NullStmt +} + +void Inst() { + int i; + TemplUses(i); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-use_device-clause.c b/clang/test/SemaOpenACC/data-construct-use_device-clause.c new file mode 100644 index 0000000000000..c2e7fd17f8c8d --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-use_device-clause.c @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +typedef struct IsComplete { + struct S { int A; } CompositeMember; + int ScalarMember; + float ArrayMember[5]; + void *PointerMember; +} Complete; +void uses(int IntParam, short *PointerParam, float ArrayParam[5], Complete CompositeParam) { + int LocalInt; + short *LocalPointer; + float LocalArray[5]; + Complete LocalComposite; + // Check Appertainment: +#pragma acc host_data use_device(LocalInt) + + // Valid cases: +#pragma acc host_data use_device(LocalInt, LocalPointer, LocalArray) + ; + ; + // expected-error@+2{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(LocalComposite.ScalarMember, LocalComposite.ScalarMember) + ; + + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(LocalArray[2:1]) + + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(1 + IntParam) + ; + + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(+IntParam) + ; + + // expected-error@+2{{OpenACC sub-array length is unspecified and cannot be inferred because the subscripted value is not an array}} + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(PointerParam[2:]) + ; + + // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(ArrayParam[2:5]) + ; + + // expected-error@+2{{OpenACC sub-array specified range [2:5] would be out of the range of the subscripted array size of 5}} + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device((float*)ArrayParam[2:5]) + ; + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device((float)ArrayParam[2]) + ; + + // expected-error@+2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'data' directive}} +#pragma acc data use_device(LocalInt) + ; + // expected-error@+2{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'enter data' directive}} +#pragma acc enter data use_device(LocalInt) + // expected-error@+2{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'exit data' directive}} +#pragma acc exit data use_device(LocalInt) +} diff --git a/clang/test/SemaOpenACC/data-construct-wait-ast.cpp b/clang/test/SemaOpenACC/data-construct-wait-ast.cpp new file mode 100644 index 0000000000000..7fb82313669df --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-wait-ast.cpp @@ -0,0 +1,266 @@ +// RUN: %clang_cc1 %s -fopenacc -ast-dump | FileCheck %s + +// Test this with PCH. +// RUN: %clang_cc1 %s -fopenacc -emit-pch -o %t %s +// RUN: %clang_cc1 %s -fopenacc -include-pch %t -ast-dump-all | FileCheck %s + +#ifndef PCH_HELPER +#define PCH_HELPER + +int some_int(); +long some_long(); + +void NormalUses() { + // CHECK: FunctionDecl{{.*}}NormalUses + // CHECK-NEXT: CompoundStmt + + int I; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + +#pragma acc data copyin(I) wait + ; + // CHECK-NEXT: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'int' + // CHECK-NEXT: wait clause + // CHECK-NEXT: <<>> + // CHECK-NEXT: NullStmt +#pragma acc enter data copyin(I) wait() + // CHECK: OpenACCEnterDataConstruct{{.*}}enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'int' + // CHECK-NEXT: wait clause + // CHECK-NEXT: <<>> +#pragma acc exit data copyout(I) wait(some_int(), some_long()) + // CHECK: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}} 'I' 'int' + // CHECK-NEXT: wait clause + // CHECK-NEXT: <<>> + // CHECK-NEXT: CallExpr{{.*}}'int' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'int (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'int ()' lvalue Function{{.*}} 'some_int' 'int ()' + // CHECK-NEXT: CallExpr{{.*}}'long' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'long (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'long ()' lvalue Function{{.*}} 'some_long' 'long ()' +#pragma acc data copyin(I) wait(queues:some_int(), some_long()) + ; + // CHECK: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'int' + // CHECK-NEXT: wait clause has queues tag + // CHECK-NEXT: <<>> + // CHECK-NEXT: CallExpr{{.*}}'int' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'int (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'int ()' lvalue Function{{.*}} 'some_int' 'int ()' + // CHECK-NEXT: CallExpr{{.*}}'long' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'long (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'long ()' lvalue Function{{.*}} 'some_long' 'long ()' + // CHECK-NEXT: NullStmt +#pragma acc enter data copyin(I) wait(devnum: some_int() :some_int(), some_long()) + // CHECK: OpenACCEnterDataConstruct{{.*}}enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'int' + // CHECK-NEXT: wait clause has devnum + // CHECK-NEXT: CallExpr{{.*}}'int' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'int (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'int ()' lvalue Function{{.*}} 'some_int' 'int ()' + // CHECK-NEXT: CallExpr{{.*}}'int' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'int (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'int ()' lvalue Function{{.*}} 'some_int' 'int ()' + // CHECK-NEXT: CallExpr{{.*}}'long' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'long (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'long ()' lvalue Function{{.*}} 'some_long' 'long ()' +#pragma acc exit data copyout(I) wait(devnum: some_int() : queues :some_int(), some_long()) wait(devnum: some_int() : queues :some_int(), some_long()) + // CHECK: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}} 'I' 'int' + // CHECK-NEXT: wait clause has devnum has queues tag + // CHECK-NEXT: CallExpr{{.*}}'int' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'int (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'int ()' lvalue Function{{.*}} 'some_int' 'int ()' + // CHECK-NEXT: CallExpr{{.*}}'int' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'int (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'int ()' lvalue Function{{.*}} 'some_int' 'int ()' + // CHECK-NEXT: CallExpr{{.*}}'long' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'long (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'long ()' lvalue Function{{.*}} 'some_long' 'long ()' + // CHECK-NEXT: wait clause has devnum has queues tag + // CHECK-NEXT: CallExpr{{.*}}'int' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'int (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'int ()' lvalue Function{{.*}} 'some_int' 'int ()' + // CHECK-NEXT: CallExpr{{.*}}'int' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'int (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'int ()' lvalue Function{{.*}} 'some_int' 'int ()' + // CHECK-NEXT: CallExpr{{.*}}'long' + // CHECK-NEXT: ImplicitCastExpr{{.*}}'long (*)()' + // CHECK-NEXT: DeclRefExpr{{.*}}'long ()' lvalue Function{{.*}} 'some_long' 'long ()' +} + +template +void TemplUses(U u) { + // CHECK: FunctionTemplateDecl + // CHECK-NEXT: TemplateTypeParmDecl{{.*}}typename depth 0 index 0 U + // CHECK-NEXT: FunctionDecl{{.*}} TemplUses 'void (U)' + // CHECK-NEXT: ParmVarDecl{{.*}} referenced u 'U' + // CHECK-NEXT: CompoundStmt + + U I; + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + +#pragma acc data copyin(I) wait + ; + // CHECK: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'U' + // CHECK-NEXT: wait clause + // CHECK-NEXT: <<>> + // CHECK-NEXT: NullStmt + +#pragma acc enter data copyin(I) wait() + // CHECK: OpenACCEnterDataConstruct{{.*}}enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'U' + // CHECK-NEXT: wait clause + // CHECK-NEXT: <<>> + +#pragma acc exit data copyout(I) wait(U::value, u) + // CHECK: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}} 'I' 'U' + // CHECK-NEXT: wait clause + // CHECK-NEXT: <<>> + // CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '' lvalue + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'U' + // CHECK-NEXT: DeclRefExpr{{.*}} 'U' lvalue ParmVar{{.*}} 'u' 'U' + +#pragma acc data copyin(I) wait(queues: U::value, u) + ; + // CHECK: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'U' + // CHECK-NEXT: wait clause has queues tag + // CHECK-NEXT: <<>> + // CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '' lvalue + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'U' + // CHECK-NEXT: DeclRefExpr{{.*}} 'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: NullStmt + +#pragma acc enter data copyin(I) wait(devnum:u:queues: U::value, u) + // CHECK: OpenACCEnterDataConstruct{{.*}}data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'U' + // CHECK-NEXT: wait clause has devnum has queues tag + // CHECK-NEXT: DeclRefExpr{{.*}} 'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '' lvalue + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'U' + // CHECK-NEXT: DeclRefExpr{{.*}} 'U' lvalue ParmVar{{.*}} 'u' 'U' + +#pragma acc exit data copyout(I) wait(devnum:u: U::value, u) + // CHECK: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}} 'I' 'U' + // CHECK-NEXT: wait clause has devnum + // CHECK-NEXT: DeclRefExpr{{.*}} 'U' lvalue ParmVar{{.*}} 'u' 'U' + // CHECK-NEXT: DependentScopeDeclRefExpr{{.*}} '' lvalue + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'U' + // CHECK-NEXT: DeclRefExpr{{.*}} 'U' lvalue ParmVar{{.*}} 'u' 'U' + + // Check the instantiated versions of the above. + // CHECK: FunctionDecl{{.*}} used TemplUses 'void (HasInt)' implicit_instantiation + // CHECK-NEXT: TemplateArgument type 'HasInt' + // CHECK-NEXT: RecordType{{.*}} 'HasInt' + // CHECK-NEXT: CXXRecord{{.*}} 'HasInt' + // CHECK-NEXT: ParmVarDecl{{.*}} used u 'HasInt' + // CHECK-NEXT: CompoundStmt + + // CHECK-NEXT: DeclStmt + // CHECK-NEXT: VarDecl + + // CHECK: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'HasInt' + // CHECK-NEXT: wait clause + // CHECK-NEXT: <<>> + // CHECK-NEXT: NullStmt + + // CHECK: OpenACCEnterDataConstruct{{.*}}enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'HasInt' + // CHECK-NEXT: wait clause + // CHECK-NEXT: <<>> + + // CHECK: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}} 'I' 'HasInt' + // CHECK-NEXT: wait clause + // CHECK-NEXT: <<>> + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}} 'const int' lvalue Var{{.*}} 'value' 'const int' + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'HasInt' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'char' + // CHECK-NEXT: CXXMemberCallExpr{{.*}}'char' + // CHECK-NEXT: MemberExpr{{.*}} '' .operator char + // CHECK-NEXT: DeclRefExpr{{.*}} 'HasInt' lvalue ParmVar + + // CHECK: OpenACCDataConstruct{{.*}}data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'HasInt' + // CHECK-NEXT: wait clause has queues tag + // CHECK-NEXT: <<>> + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}} 'const int' lvalue Var{{.*}} 'value' 'const int' + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'HasInt' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'char' + // CHECK-NEXT: CXXMemberCallExpr{{.*}}'char' + // CHECK-NEXT: MemberExpr{{.*}} '' .operator char + // CHECK-NEXT: DeclRefExpr{{.*}} 'HasInt' lvalue ParmVar + // CHECK-NEXT: NullStmt + + // CHECK: OpenACCEnterDataConstruct{{.*}}enter data + // CHECK-NEXT: copyin clause + // CHECK-NEXT: DeclRefExpr{{.*}}'I' 'HasInt' + // CHECK-NEXT: wait clause has devnum has queues tag + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'char' + // CHECK-NEXT: CXXMemberCallExpr{{.*}}'char' + // CHECK-NEXT: MemberExpr{{.*}} '' .operator char + // CHECK-NEXT: DeclRefExpr{{.*}} 'HasInt' lvalue ParmVar + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}} 'const int' lvalue Var{{.*}} 'value' 'const int' + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'HasInt' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'char' + // CHECK-NEXT: CXXMemberCallExpr{{.*}}'char' + // CHECK-NEXT: MemberExpr{{.*}} '' .operator char + // CHECK-NEXT: DeclRefExpr{{.*}} 'HasInt' lvalue ParmVar + + // CHECK: OpenACCExitDataConstruct{{.*}}exit data + // CHECK-NEXT: copyout clause + // CHECK-NEXT: DeclRefExpr{{.*}} 'I' 'HasInt' + // CHECK-NEXT: wait clause has devnum + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'char' + // CHECK-NEXT: CXXMemberCallExpr{{.*}}'char' + // CHECK-NEXT: MemberExpr{{.*}} '' .operator char + // CHECK-NEXT: DeclRefExpr{{.*}} 'HasInt' lvalue ParmVar + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' + // CHECK-NEXT: DeclRefExpr{{.*}} 'const int' lvalue Var{{.*}} 'value' 'const int' + // CHECK-NEXT: NestedNameSpecifier TypeSpec 'HasInt' + // CHECK-NEXT: ImplicitCastExpr{{.*}} 'char' + // CHECK-NEXT: CXXMemberCallExpr{{.*}}'char' + // CHECK-NEXT: MemberExpr{{.*}} '' .operator char + // CHECK-NEXT: DeclRefExpr{{.*}} 'HasInt' lvalue ParmVar +} + +struct HasInt { + using IntTy = int; + using ShortTy = short; + static constexpr int value = 1; + + operator char(); +}; + +void Inst() { + TemplUses({}); +} +#endif diff --git a/clang/test/SemaOpenACC/data-construct-wait-clause.c b/clang/test/SemaOpenACC/data-construct-wait-clause.c new file mode 100644 index 0000000000000..cef2dbdca29ed --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct-wait-clause.c @@ -0,0 +1,41 @@ +// RUN: %clang_cc1 %s -fopenacc -verify + +struct NotConvertible{} NC; +short getS(); +int getI(); + +void uses() { + int arr[5]; + +#pragma acc data copyin(arr[0]) wait + ; + +#pragma acc enter data copyin(arr[0]) wait() + +#pragma acc exit data copyout(arr[0]) wait(getS(), getI()) + + // expected-error@+1{{OpenACC 'wait' clause is not valid on 'host_data' directive}} +#pragma acc host_data use_device(arr) wait(getS(), getI()) + ; + +#pragma acc data copyin(arr[0]) wait(devnum:getS(): getI()) + ; + +#pragma acc enter data copyin(arr[0]) wait(devnum:getS(): queues: getI()) wait(devnum:getI(): queues: getS(), getI(), 5) + + // expected-error@+1{{OpenACC clause 'wait' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc exit data copyout(arr[0]) wait(devnum:NC : 5) + + // expected-error@+1{{OpenACC clause 'wait' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc data copyin(arr[0]) wait(devnum:5 : NC) + ; + + // expected-error@+3{{OpenACC clause 'wait' requires expression of integer type ('int[5]' invalid)}} + // expected-error@+2{{OpenACC clause 'wait' requires expression of integer type ('int[5]' invalid)}} + // expected-error@+1{{OpenACC clause 'wait' requires expression of integer type ('struct NotConvertible' invalid)}} +#pragma acc enter data copyin(arr[0]) wait(devnum:arr : queues: arr, NC, 5) + + // expected-error@+1{{OpenACC 'wait' clause is not valid on 'loop' directive}} +#pragma acc loop wait + for(int i = 5; i < 10;++i); +} diff --git a/clang/test/SemaOpenACC/data-construct.cpp b/clang/test/SemaOpenACC/data-construct.cpp new file mode 100644 index 0000000000000..4c868b68e332e --- /dev/null +++ b/clang/test/SemaOpenACC/data-construct.cpp @@ -0,0 +1,201 @@ +// RUN: %clang_cc1 %s -fopenacc -verify -Wno-empty-body -Wno-unused-value + +void HasStmt() { + { + // expected-error@+2{{expected statement}} +#pragma acc data default(none) + } + + int I; + { + // expected-error@+2{{expected statement}} +#pragma acc host_data use_device(I) + } + // Don't have statements, so this is fine. + { +#pragma acc enter data copyin(I) + } + { +#pragma acc exit data copyout(I) + } +} + +void AtLeastOneOf() { + int Var; + int *VarPtr = &Var; +// Data +#pragma acc data copy(Var) + ; +#pragma acc data copyin(Var) + ; +#pragma acc data copyout(Var) + ; +#pragma acc data create(Var) + ; +#pragma acc data no_create(Var) + ; +#pragma acc data present(Var) + ; +#pragma acc data deviceptr(VarPtr) + ; +#pragma acc data attach(VarPtr) + ; +#pragma acc data default(none) + ; + + // expected-error@+1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} +#pragma acc data if(Var) + ; + + // expected-error@+1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} +#pragma acc data async + ; + + // expected-error@+1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} +#pragma acc data wait + ; + + // expected-error@+1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} +#pragma acc data device_type(*) + ; + // expected-error@+1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} +#pragma acc data + ; + + // Enter Data +#pragma acc enter data copyin(Var) +#pragma acc enter data create(Var) +#pragma acc enter data attach(VarPtr) + + // expected-error@+1{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} +#pragma acc enter data if(Var) + // expected-error@+1{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} +#pragma acc enter data async + // expected-error@+1{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} +#pragma acc enter data wait + // expected-error@+1{{OpenACC 'enter data' construct must have at least one 'copyin', 'create' or 'attach' clause}} +#pragma acc enter data + + // Exit Data +#pragma acc exit data copyout(Var) +#pragma acc exit data delete(Var) +#pragma acc exit data detach(VarPtr) + + // expected-error@+1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} +#pragma acc exit data if(Var) + // expected-error@+1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} +#pragma acc exit data async + // expected-error@+1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} +#pragma acc exit data wait + // expected-error@+1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} +#pragma acc exit data finalize + // expected-error@+1{{OpenACC 'exit data' construct must have at least one 'copyout', 'delete' or 'detach' clause}} +#pragma acc exit data + + // Host Data +#pragma acc host_data use_device(Var) + ; + + // expected-error@+1{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} +#pragma acc host_data if(Var) + ; + // expected-error@+1{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} +#pragma acc host_data if_present + ; + // expected-error@+1{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} +#pragma acc host_data + ; +} + +void DataRules() { + int Var; + // expected-error@+2{{OpenACC clause 'copy' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(*) copy(Var) + ; + // expected-error@+2{{OpenACC clause 'copyin' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(*) copyin(Var) + ; + // expected-error@+2{{OpenACC clause 'copyout' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(*) copyout(Var) + ; + // expected-error@+2{{OpenACC clause 'create' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(*) create(Var) + ; + // expected-error@+2{{OpenACC clause 'no_create' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(*) no_create(Var) + ; + // expected-error@+2{{OpenACC clause 'present' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(*) present(Var) + ; + // expected-error@+2{{OpenACC clause 'deviceptr' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(*) deviceptr(Var) + ; + // expected-error@+2{{OpenACC clause 'attach' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(*) attach(Var) + ; + // expected-error@+2{{OpenACC clause 'default' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(*) default(none) + ; + // expected-error@+2{{OpenACC clause 'if' may not follow a 'device_type' clause in a 'data' construct}} + // expected-note@+1{{previous clause is here}} +#pragma acc data default(none) device_type(*) if(Var) + ; +#pragma acc data default(none) device_type(*) async + ; +#pragma acc data default(none) device_type(*) wait + ; +} + +struct HasMembers { + int Member; + + void HostDataError() { + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(this) + ; + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(this->Member) + ; + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(Member) + ; + } +}; + +void HostDataRules() { + int Var, Var2; + // expected-error@+3{{OpenACC 'host_data' construct must have at least one 'use_device' clause}} + // expected-error@+2{{OpenACC 'if' clause cannot appear more than once on a 'host_data' directive}} + // expected-note@+1{{previous clause is here}} +#pragma acc host_data if(Var) if (Var2) + ; + +#pragma acc host_data use_device(Var) + ; + + int Array[5]; +#pragma acc host_data use_device(Array) + ; + + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(Array[1:1]) + ; + + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(Array[1]) + ; + HasMembers HM; + // expected-error@+1{{OpenACC variable in 'use_device' clause is not a valid variable name or array name}} +#pragma acc host_data use_device(HM.Member) + ; + +} diff --git a/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c b/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c index ecf2835776673..d196633c8b6d9 100644 --- a/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c +++ b/clang/test/SemaOpenACC/loop-construct-auto_seq_independent-clauses.c @@ -37,10 +37,10 @@ void uses() { int *VarPtr; // 'auto' can combine with any other clause. - // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}} #pragma acc loop auto finalize for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}} #pragma acc loop auto if_present for(unsigned i = 0; i < 5; ++i); #pragma acc loop auto worker @@ -68,16 +68,16 @@ void uses() { // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} #pragma acc loop auto present_or_copy(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'loop' directive}} #pragma acc loop auto use_device(Var) for(unsigned i = 0; i < 5; ++i); // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} #pragma acc loop auto attach(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'loop' directive}} #pragma acc loop auto delete(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'loop' directive}} #pragma acc loop auto detach(Var) for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} @@ -171,10 +171,10 @@ void uses() { #pragma acc loop auto wait for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}} #pragma acc loop finalize auto for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}} #pragma acc loop if_present auto for(unsigned i = 0; i < 5; ++i); #pragma acc loop worker auto @@ -202,16 +202,16 @@ void uses() { // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} #pragma acc loop present_or_copy(Var) auto for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'loop' directive}} #pragma acc loop use_device(Var) auto for(unsigned i = 0; i < 5; ++i); // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} #pragma acc loop attach(Var) auto for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'loop' directive}} #pragma acc loop delete(Var) auto for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'loop' directive}} #pragma acc loop detach(Var) auto for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} @@ -306,10 +306,10 @@ void uses() { for(unsigned i = 0; i < 5; ++i); // 'independent' can also be combined with any clauses - // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}} #pragma acc loop independent finalize for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}} #pragma acc loop independent if_present for(unsigned i = 0; i < 5; ++i); #pragma acc loop independent worker @@ -337,16 +337,16 @@ void uses() { // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} #pragma acc loop independent present_or_copy(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'loop' directive}} #pragma acc loop independent use_device(Var) for(unsigned i = 0; i < 5; ++i); // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} #pragma acc loop independent attach(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'loop' directive}} #pragma acc loop independent delete(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'loop' directive}} #pragma acc loop independent detach(Var) for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} @@ -440,10 +440,10 @@ void uses() { #pragma acc loop independent wait for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}} #pragma acc loop finalize independent for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}} #pragma acc loop if_present independent for(unsigned i = 0; i < 5; ++i); #pragma acc loop worker independent @@ -471,16 +471,16 @@ void uses() { // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} #pragma acc loop present_or_copy(Var) independent for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'loop' directive}} #pragma acc loop use_device(Var) independent for(unsigned i = 0; i < 5; ++i); // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} #pragma acc loop attach(Var) independent for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'loop' directive}} #pragma acc loop delete(Var) independent for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'loop' directive}} #pragma acc loop detach(Var) independent for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} @@ -587,10 +587,10 @@ void uses() { // expected-note@+1{{previous clause is here}} #pragma acc loop seq vector for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}} #pragma acc loop seq finalize for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}} #pragma acc loop seq if_present for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} @@ -614,16 +614,16 @@ void uses() { // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} #pragma acc loop seq present_or_copy(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'loop' directive}} #pragma acc loop seq use_device(Var) for(unsigned i = 0; i < 5; ++i); // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} #pragma acc loop seq attach(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'loop' directive}} #pragma acc loop seq delete(Var) for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'loop' directive}} #pragma acc loop seq detach(Var) for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} @@ -727,10 +727,10 @@ void uses() { // expected-note@+1{{previous clause is here}} #pragma acc loop vector seq for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'finalize' not yet implemented}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}} #pragma acc loop finalize seq for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'if_present' not yet implemented}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}} #pragma acc loop if_present seq for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'nohost' not yet implemented}} @@ -754,16 +754,16 @@ void uses() { // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} #pragma acc loop present_or_copy(Var) seq for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'use_device' not yet implemented}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'loop' directive}} #pragma acc loop use_device(Var) seq for(unsigned i = 0; i < 5; ++i); // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} #pragma acc loop attach(Var) seq for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'delete' not yet implemented}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'loop' directive}} #pragma acc loop delete(Var) seq for(unsigned i = 0; i < 5; ++i); - // expected-warning@+1{{OpenACC clause 'detach' not yet implemented}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'loop' directive}} #pragma acc loop detach(Var) seq for(unsigned i = 0; i < 5; ++i); // expected-warning@+1{{OpenACC clause 'device' not yet implemented}} diff --git a/clang/test/SemaOpenACC/loop-construct-collapse-clause.cpp b/clang/test/SemaOpenACC/loop-construct-collapse-clause.cpp index dc954e36d765d..4d45d1107d03b 100644 --- a/clang/test/SemaOpenACC/loop-construct-collapse-clause.cpp +++ b/clang/test/SemaOpenACC/loop-construct-collapse-clause.cpp @@ -323,14 +323,17 @@ void no_other_directives() { #pragma acc loop collapse(2) for(unsigned i = 0; i < 5; ++i) { for(unsigned j = 0; j < 5; ++j) { -#pragma acc data // expected-warning{{OpenACC construct 'data' not yet implemented}} + // expected-error@+1{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} +#pragma acc data + ; } } // expected-note@+1{{active 'collapse' clause defined here}} #pragma acc loop collapse(2) for(unsigned i = 0; i < 5; ++i) { + // expected-error@+2{{OpenACC 'data' construct must have at least one 'copy', 'copyin', 'copyout', 'create', 'no_create', 'present', 'deviceptr', 'attach' or 'default' clause}} // expected-error@+1{{OpenACC 'data' construct cannot appear in intervening code of a 'loop' with a 'collapse' clause}} -#pragma acc data // expected-warning{{OpenACC construct 'data' not yet implemented}} +#pragma acc data for(unsigned j = 0; j < 5; ++j) { } } diff --git a/clang/test/SemaOpenACC/loop-construct-device_type-clause.c b/clang/test/SemaOpenACC/loop-construct-device_type-clause.c index 94406de079cdc..3e4d0da60b6b2 100644 --- a/clang/test/SemaOpenACC/loop-construct-device_type-clause.c +++ b/clang/test/SemaOpenACC/loop-construct-device_type-clause.c @@ -41,12 +41,10 @@ void uses() { #pragma acc loop device_type(*) vector for(int i = 0; i < 5; ++i); - // expected-error@+2{{OpenACC clause 'finalize' may not follow a 'device_type' clause in a 'loop' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'finalize' clause is not valid on 'loop' directive}} #pragma acc loop device_type(*) finalize for(int i = 0; i < 5; ++i); - // expected-error@+2{{OpenACC clause 'if_present' may not follow a 'device_type' clause in a 'loop' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'if_present' clause is not valid on 'loop' directive}} #pragma acc loop device_type(*) if_present for(int i = 0; i < 5; ++i); #pragma acc loop device_type(*) seq @@ -82,19 +80,16 @@ void uses() { // expected-error@+1{{OpenACC 'present_or_copy' clause is not valid on 'loop' directive}} #pragma acc loop device_type(*) present_or_copy(Var) for(int i = 0; i < 5; ++i); - // expected-error@+2{{OpenACC clause 'use_device' may not follow a 'device_type' clause in a 'loop' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'use_device' clause is not valid on 'loop' directive}} #pragma acc loop device_type(*) use_device(Var) for(int i = 0; i < 5; ++i); // expected-error@+1{{OpenACC 'attach' clause is not valid on 'loop' directive}} #pragma acc loop device_type(*) attach(Var) for(int i = 0; i < 5; ++i); - // expected-error@+2{{OpenACC clause 'delete' may not follow a 'device_type' clause in a 'loop' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'delete' clause is not valid on 'loop' directive}} #pragma acc loop device_type(*) delete(Var) for(int i = 0; i < 5; ++i); - // expected-error@+2{{OpenACC clause 'detach' may not follow a 'device_type' clause in a 'loop' construct}} - // expected-note@+1{{previous clause is here}} + // expected-error@+1{{OpenACC 'detach' clause is not valid on 'loop' directive}} #pragma acc loop device_type(*) detach(Var) for(int i = 0; i < 5; ++i); // expected-error@+2{{OpenACC clause 'device' may not follow a 'device_type' clause in a 'loop' construct}} diff --git a/clang/test/SemaOpenACC/loop-construct-gang-clause.cpp b/clang/test/SemaOpenACC/loop-construct-gang-clause.cpp index a2bda5a7e82f6..6b4c03bbc50c6 100644 --- a/clang/test/SemaOpenACC/loop-construct-gang-clause.cpp +++ b/clang/test/SemaOpenACC/loop-construct-gang-clause.cpp @@ -278,7 +278,7 @@ void Kernels() { #pragma acc kernels #pragma acc loop gang(num:1) for(int j = 0; j < 5; ++j) { - // expected-error@+2{{loop with a 'gang' clause may not exist in the region of a 'gang' clause on a 'kernels' compute construct}} + // expected-error@+2{{loop with a 'gang' clause may not exist in the region of a 'gang' clause on a 'kernels' construct}} // expected-note@-3{{previous clause is here}} #pragma acc loop gang(static:1) for(int i = 0; i < 5; ++i); diff --git a/clang/test/SemaOpenACC/loop-construct-vector-clause.cpp b/clang/test/SemaOpenACC/loop-construct-vector-clause.cpp index 3260e368fbb42..1fed82c510208 100644 --- a/clang/test/SemaOpenACC/loop-construct-vector-clause.cpp +++ b/clang/test/SemaOpenACC/loop-construct-vector-clause.cpp @@ -18,12 +18,12 @@ void TemplUses(Int I, NotInt NI, ConvertsToInt CTI) { #pragma acc loop vector(length: NI) for(int j = 0; j < 5; ++j); - // expected-error@+2{{'num' argument on 'vector' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}} + // expected-error@+2{{'length' argument on 'vector' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}} #pragma acc serial #pragma acc loop vector(length: I) for(int j = 0; j < 5; ++j); - // expected-error@+3{{'num' argument to 'vector' clause not allowed on a 'loop' construct associated with a 'kernels' construct that has a 'vector_length' clause}} + // expected-error@+3{{'length' argument to 'vector' clause not allowed on a 'loop' construct associated with a 'kernels' construct that has a 'vector_length' clause}} // expected-note@+1{{previous clause is here}} #pragma acc kernels vector_length(I) #pragma acc loop vector(length: CTI) @@ -87,12 +87,12 @@ void uses() { #pragma acc loop vector(length: NI) for(int j = 0; j < 5; ++j); - // expected-error@+2{{'num' argument on 'vector' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}} + // expected-error@+2{{'length' argument on 'vector' clause is not permitted on a 'loop' construct associated with a 'serial' compute construct}} #pragma acc serial #pragma acc loop vector(length: i) for(int j = 0; j < 5; ++j); - // expected-error@+3{{'num' argument to 'vector' clause not allowed on a 'loop' construct associated with a 'kernels' construct that has a 'vector_length' clause}} + // expected-error@+3{{'length' argument to 'vector' clause not allowed on a 'loop' construct associated with a 'kernels' construct that has a 'vector_length' clause}} // expected-note@+1{{previous clause is here}} #pragma acc kernels vector_length(i) #pragma acc loop vector(length: i) diff --git a/clang/tools/clang-format/git-clang-format b/clang/tools/clang-format/git-clang-format index a322d4abf0ec2..da271bbe6e3a0 100755 --- a/clang/tools/clang-format/git-clang-format +++ b/clang/tools/clang-format/git-clang-format @@ -1,12 +1,12 @@ #!/usr/bin/env python3 # -#===- git-clang-format - ClangFormat Git Integration ---------*- python -*--===# +# ===- git-clang-format - ClangFormat Git Integration -------*- python -*--=== # # # 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 # -#===------------------------------------------------------------------------===# +# ===----------------------------------------------------------------------=== # r""" clang-format git integration @@ -32,10 +32,11 @@ import re import subprocess import sys -usage = ('git clang-format [OPTIONS] [] [|--staged] ' - '[--] [...]') +usage = ( + "git clang-format [OPTIONS] [] [|--staged] [--] [...]" +) -desc = ''' +desc = """ If zero or one commits are given, run clang-format on all lines that differ between the working directory and , which defaults to HEAD. Changes are only applied to the working directory, or in the stage/index. @@ -58,639 +59,815 @@ The following git-config settings set the default of the corresponding option: clangFormat.commit clangFormat.extensions clangFormat.style -''' +""" # Name of the temporary index file in which save the output of clang-format. # This file is created within the .git directory. -temp_index_basename = 'clang-format-index' +temp_index_basename = "clang-format-index" -Range = collections.namedtuple('Range', 'start, count') +Range = collections.namedtuple("Range", "start, count") def main(): - config = load_git_config() - - # In order to keep '--' yet allow options after positionals, we need to - # check for '--' ourselves. (Setting nargs='*' throws away the '--', while - # nargs=argparse.REMAINDER disallows options after positionals.) - argv = sys.argv[1:] - try: - idx = argv.index('--') - except ValueError: - dash_dash = [] - else: - dash_dash = argv[idx:] - argv = argv[:idx] - - default_extensions = ','.join([ - # From clang/lib/Frontend/FrontendOptions.cpp, all lower case - 'c', 'h', # C - 'm', # ObjC - 'mm', # ObjC++ - 'cc', 'cp', 'cpp', 'c++', 'cxx', 'hh', 'hpp', 'hxx', 'inc', # C++ - 'ccm', 'cppm', 'cxxm', 'c++m', # C++ Modules - 'cu', 'cuh', # CUDA - # Other languages that clang-format supports - 'proto', 'protodevel', # Protocol Buffers - 'java', # Java - 'js', 'mjs', 'cjs', # JavaScript - 'ts', # TypeScript - 'cs', # C Sharp - 'json', # Json - 'sv', 'svh', 'v', 'vh', # Verilog - 'td', # TableGen - 'txtpb', 'textpb', 'pb.txt', 'textproto', 'asciipb', # TextProto - ]) - - p = argparse.ArgumentParser( - usage=usage, formatter_class=argparse.RawDescriptionHelpFormatter, - description=desc) - p.add_argument('--binary', - default=config.get('clangformat.binary', 'clang-format'), - help='path to clang-format'), - p.add_argument('--commit', - default=config.get('clangformat.commit', 'HEAD'), - help='default commit to use if none is specified'), - p.add_argument('--diff', action='store_true', - help='print a diff instead of applying the changes') - p.add_argument('--diffstat', action='store_true', - help='print a diffstat instead of applying the changes') - p.add_argument('--extensions', - default=config.get('clangformat.extensions', - default_extensions), - help=('comma-separated list of file extensions to format, ' - 'excluding the period and case-insensitive')), - p.add_argument('-f', '--force', action='store_true', - help='allow changes to unstaged files') - p.add_argument('-p', '--patch', action='store_true', - help='select hunks interactively') - p.add_argument('-q', '--quiet', action='count', default=0, - help='print less information') - p.add_argument('--staged', '--cached', action='store_true', - help='format lines in the stage instead of the working dir') - p.add_argument('--style', - default=config.get('clangformat.style', None), - help='passed to clang-format'), - p.add_argument('-v', '--verbose', action='count', default=0, - help='print extra information') - p.add_argument('--diff_from_common_commit', action='store_true', - help=('diff from the last common commit for commits in ' - 'separate branches rather than the exact point of the ' - 'commits')) - # We gather all the remaining positional arguments into 'args' since we need - # to use some heuristics to determine whether or not was present. - # However, to print pretty messages, we make use of metavar and help. - p.add_argument('args', nargs='*', metavar='', - help='revision from which to compute the diff') - p.add_argument('ignored', nargs='*', metavar='...', - help='if specified, only consider differences in these files') - opts = p.parse_args(argv) - - opts.verbose -= opts.quiet - del opts.quiet - - commits, files = interpret_args(opts.args, dash_dash, opts.commit) - if len(commits) > 2: - die('at most two commits allowed; %d given' % len(commits)) - if len(commits) == 2: - if opts.staged: - die('--staged is not allowed when two commits are given') - if not opts.diff: - die('--diff is required when two commits are given') - elif opts.diff_from_common_commit: - die('--diff_from_common_commit is only allowed when two commits are given') - - if os.path.dirname(opts.binary): - opts.binary = os.path.abspath(opts.binary) - - changed_lines = compute_diff_and_extract_lines(commits, - files, - opts.staged, - opts.diff_from_common_commit) - if opts.verbose >= 1: - ignored_files = set(changed_lines) - filter_by_extension(changed_lines, opts.extensions.lower().split(',')) - # The computed diff outputs absolute paths, so we must cd before accessing - # those files. - cd_to_toplevel() - filter_symlinks(changed_lines) - filter_ignored_files(changed_lines, binary=opts.binary) - if opts.verbose >= 1: - ignored_files.difference_update(changed_lines) - if ignored_files: - print('Ignoring the following files (wrong extension, symlink, or ' - 'ignored by clang-format):') - for filename in ignored_files: - print(' %s' % filename) - if changed_lines: - print('Running clang-format on the following files:') - for filename in changed_lines: - print(' %s' % filename) - - if not changed_lines: - if opts.verbose >= 0: - print('no modified files to format') - return 0 - - if len(commits) > 1: - old_tree = commits[1] - revision = old_tree - elif opts.staged: - old_tree = create_tree_from_index(changed_lines) - revision = '' - else: - old_tree = create_tree_from_workdir(changed_lines) - revision = None - new_tree = run_clang_format_and_save_to_tree(changed_lines, - revision, - binary=opts.binary, - style=opts.style) - if opts.verbose >= 1: - print('old tree: %s' % old_tree) - print('new tree: %s' % new_tree) - - if old_tree == new_tree: - if opts.verbose >= 0: - print('clang-format did not modify any files') - return 0 - - if opts.diff: - return print_diff(old_tree, new_tree) - if opts.diffstat: - return print_diffstat(old_tree, new_tree) - - changed_files = apply_changes(old_tree, new_tree, force=opts.force, - patch_mode=opts.patch) - if (opts.verbose >= 0 and not opts.patch) or opts.verbose >= 1: - print('changed files:') - for filename in changed_files: - print(' %s' % filename) - - return 1 + config = load_git_config() + + # In order to keep '--' yet allow options after positionals, we need to + # check for '--' ourselves. (Setting nargs='*' throws away the '--', while + # nargs=argparse.REMAINDER disallows options after positionals.) + argv = sys.argv[1:] + try: + idx = argv.index("--") + except ValueError: + dash_dash = [] + else: + dash_dash = argv[idx:] + argv = argv[:idx] + + default_extensions = ",".join( + [ + # From clang/lib/Frontend/FrontendOptions.cpp, all lower case + "c", + "h", # C + "m", # ObjC + "mm", # ObjC++ + "cc", + "cp", + "cpp", + "c++", + "cxx", + "hh", + "hpp", + "hxx", + "inc", # C++ + "ccm", + "cppm", + "cxxm", + "c++m", # C++ Modules + "cu", + "cuh", # CUDA + # Other languages that clang-format supports + "proto", + "protodevel", # Protocol Buffers + "java", # Java + "js", + "mjs", + "cjs", # JavaScript + "ts", # TypeScript + "cs", # C Sharp + "json", # Json + "sv", + "svh", + "v", + "vh", # Verilog + "td", # TableGen + "txtpb", + "textpb", + "pb.txt", + "textproto", + "asciipb", # TextProto + ] + ) + + p = argparse.ArgumentParser( + usage=usage, + formatter_class=argparse.RawDescriptionHelpFormatter, + description=desc, + ) + p.add_argument( + "--binary", + default=config.get("clangformat.binary", "clang-format"), + help="path to clang-format", + ), + p.add_argument( + "--commit", + default=config.get("clangformat.commit", "HEAD"), + help="default commit to use if none is specified", + ), + p.add_argument( + "--diff", + action="store_true", + help="print a diff instead of applying the changes", + ) + p.add_argument( + "--diffstat", + action="store_true", + help="print a diffstat instead of applying the changes", + ) + p.add_argument( + "--extensions", + default=config.get("clangformat.extensions", default_extensions), + help=( + "comma-separated list of file extensions to format, " + "excluding the period and case-insensitive" + ), + ), + p.add_argument( + "-f", + "--force", + action="store_true", + help="allow changes to unstaged files", + ) + p.add_argument( + "-p", "--patch", action="store_true", help="select hunks interactively" + ) + p.add_argument( + "-q", + "--quiet", + action="count", + default=0, + help="print less information", + ) + p.add_argument( + "--staged", + "--cached", + action="store_true", + help="format lines in the stage instead of the working dir", + ) + p.add_argument( + "--style", + default=config.get("clangformat.style", None), + help="passed to clang-format", + ), + p.add_argument( + "-v", + "--verbose", + action="count", + default=0, + help="print extra information", + ) + p.add_argument( + "--diff_from_common_commit", + action="store_true", + help=( + "diff from the last common commit for commits in " + "separate branches rather than the exact point of the " + "commits" + ), + ) + # We gather all the remaining positional arguments into 'args' since we need + # to use some heuristics to determine whether or not was present. + # However, to print pretty messages, we make use of metavar and help. + p.add_argument( + "args", + nargs="*", + metavar="", + help="revision from which to compute the diff", + ) + p.add_argument( + "ignored", + nargs="*", + metavar="...", + help="if specified, only consider differences in these files", + ) + opts = p.parse_args(argv) + + opts.verbose -= opts.quiet + del opts.quiet + + commits, files = interpret_args(opts.args, dash_dash, opts.commit) + if len(commits) > 2: + die("at most two commits allowed; %d given" % len(commits)) + if len(commits) == 2: + if opts.staged: + die("--staged is not allowed when two commits are given") + if not opts.diff: + die("--diff is required when two commits are given") + elif opts.diff_from_common_commit: + die( + "--diff_from_common_commit is only allowed when two commits are " + "given" + ) + + if os.path.dirname(opts.binary): + opts.binary = os.path.abspath(opts.binary) + + changed_lines = compute_diff_and_extract_lines( + commits, files, opts.staged, opts.diff_from_common_commit + ) + if opts.verbose >= 1: + ignored_files = set(changed_lines) + filter_by_extension(changed_lines, opts.extensions.lower().split(",")) + # The computed diff outputs absolute paths, so we must cd before accessing + # those files. + cd_to_toplevel() + filter_symlinks(changed_lines) + filter_ignored_files(changed_lines, binary=opts.binary) + if opts.verbose >= 1: + ignored_files.difference_update(changed_lines) + if ignored_files: + print( + "Ignoring the following files (wrong extension, symlink, or " + "ignored by clang-format):" + ) + for filename in ignored_files: + print(" %s" % filename) + if changed_lines: + print("Running clang-format on the following files:") + for filename in changed_lines: + print(" %s" % filename) + + if not changed_lines: + if opts.verbose >= 0: + print("no modified files to format") + return 0 + + if len(commits) > 1: + old_tree = commits[1] + revision = old_tree + elif opts.staged: + old_tree = create_tree_from_index(changed_lines) + revision = "" + else: + old_tree = create_tree_from_workdir(changed_lines) + revision = None + new_tree = run_clang_format_and_save_to_tree( + changed_lines, revision, binary=opts.binary, style=opts.style + ) + if opts.verbose >= 1: + print("old tree: %s" % old_tree) + print("new tree: %s" % new_tree) + + if old_tree == new_tree: + if opts.verbose >= 0: + print("clang-format did not modify any files") + return 0 + + if opts.diff: + return print_diff(old_tree, new_tree) + if opts.diffstat: + return print_diffstat(old_tree, new_tree) + + changed_files = apply_changes( + old_tree, new_tree, force=opts.force, patch_mode=opts.patch + ) + if (opts.verbose >= 0 and not opts.patch) or opts.verbose >= 1: + print("changed files:") + for filename in changed_files: + print(" %s" % filename) + + return 1 def load_git_config(non_string_options=None): - """Return the git configuration as a dictionary. - - All options are assumed to be strings unless in `non_string_options`, in which - is a dictionary mapping option name (in lower case) to either "--bool" or - "--int".""" - if non_string_options is None: - non_string_options = {} - out = {} - for entry in run('git', 'config', '--list', '--null').split('\0'): - if entry: - if '\n' in entry: - name, value = entry.split('\n', 1) - else: - # A setting with no '=' ('\n' with --null) is implicitly 'true' - name = entry - value = 'true' - if name in non_string_options: - value = run('git', 'config', non_string_options[name], name) - out[name] = value - return out + """Return the git configuration as a dictionary. + + All options are assumed to be strings unless in `non_string_options`, in + which is a dictionary mapping option name (in lower case) to either "--bool" + or "--int".""" + if non_string_options is None: + non_string_options = {} + out = {} + for entry in run("git", "config", "--list", "--null").split("\0"): + if entry: + if "\n" in entry: + name, value = entry.split("\n", 1) + else: + # A setting with no '=' ('\n' with --null) is implicitly 'true' + name = entry + value = "true" + if name in non_string_options: + value = run("git", "config", non_string_options[name], name) + out[name] = value + return out def interpret_args(args, dash_dash, default_commit): - """Interpret `args` as "[commits] [--] [files]" and return (commits, files). - - It is assumed that "--" and everything that follows has been removed from - args and placed in `dash_dash`. - - If "--" is present (i.e., `dash_dash` is non-empty), the arguments to its - left (if present) are taken as commits. Otherwise, the arguments are checked - from left to right if they are commits or files. If commits are not given, - a list with `default_commit` is used.""" - if dash_dash: - if len(args) == 0: - commits = [default_commit] - else: - commits = args - for commit in commits: - object_type = get_object_type(commit) - if object_type not in ('commit', 'tag'): - if object_type is None: - die("'%s' is not a commit" % commit) + """Interpret `args` as "[commits] [--] [files]" and return (commits, files). + + It is assumed that "--" and everything that follows has been removed from + args and placed in `dash_dash`. + + If "--" is present (i.e., `dash_dash` is non-empty), the arguments to its + left (if present) are taken as commits. Otherwise, the arguments are + checked from left to right if they are commits or files. If commits are not + given, a list with `default_commit` is used.""" + if dash_dash: + if len(args) == 0: + commits = [default_commit] else: - die("'%s' is a %s, but a commit was expected" % (commit, object_type)) - files = dash_dash[1:] - elif args: - commits = [] - while args: - if not disambiguate_revision(args[0]): - break - commits.append(args.pop(0)) - if not commits: - commits = [default_commit] - files = args - else: - commits = [default_commit] - files = [] - return commits, files + commits = args + for commit in commits: + object_type = get_object_type(commit) + if object_type not in ("commit", "tag"): + if object_type is None: + die("'%s' is not a commit" % commit) + else: + die( + "'%s' is a %s, but a commit was expected" + % (commit, object_type) + ) + files = dash_dash[1:] + elif args: + commits = [] + while args: + if not disambiguate_revision(args[0]): + break + commits.append(args.pop(0)) + if not commits: + commits = [default_commit] + files = args + else: + commits = [default_commit] + files = [] + return commits, files def disambiguate_revision(value): - """Returns True if `value` is a revision, False if it is a file, or dies.""" - # If `value` is ambiguous (neither a commit nor a file), the following - # command will die with an appropriate error message. - run('git', 'rev-parse', value, verbose=False) - object_type = get_object_type(value) - if object_type is None: - return False - if object_type in ('commit', 'tag'): - return True - die('`%s` is a %s, but a commit or filename was expected' % - (value, object_type)) + """Returns True if `value` is a revision, False if it is a file, or dies.""" + # If `value` is ambiguous (neither a commit nor a file), the following + # command will die with an appropriate error message. + run("git", "rev-parse", value, verbose=False) + object_type = get_object_type(value) + if object_type is None: + return False + if object_type in ("commit", "tag"): + return True + die( + "`%s` is a %s, but a commit or filename was expected" + % (value, object_type) + ) def get_object_type(value): - """Returns a string description of an object's type, or None if it is not - a valid git object.""" - cmd = ['git', 'cat-file', '-t', value] - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - if p.returncode != 0: - return None - return convert_string(stdout.strip()) + """Returns a string description of an object's type, or None if it is not + a valid git object.""" + cmd = ["git", "cat-file", "-t", value] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + if p.returncode != 0: + return None + return convert_string(stdout.strip()) def compute_diff_and_extract_lines(commits, files, staged, diff_common_commit): - """Calls compute_diff() followed by extract_lines().""" - diff_process = compute_diff(commits, files, staged, diff_common_commit) - changed_lines = extract_lines(diff_process.stdout) - diff_process.stdout.close() - diff_process.wait() - if diff_process.returncode != 0: - # Assume error was already printed to stderr. - sys.exit(2) - return changed_lines + """Calls compute_diff() followed by extract_lines().""" + diff_process = compute_diff(commits, files, staged, diff_common_commit) + changed_lines = extract_lines(diff_process.stdout) + diff_process.stdout.close() + diff_process.wait() + if diff_process.returncode != 0: + # Assume error was already printed to stderr. + sys.exit(2) + return changed_lines def compute_diff(commits, files, staged, diff_common_commit): - """Return a subprocess object producing the diff from `commits`. - - The return value's `stdin` file object will produce a patch with the - differences between the working directory (or stage if --staged is used) and - the first commit if a single one was specified, or the difference between - both specified commits, filtered on `files` (if non-empty). - Zero context lines are used in the patch.""" - git_tool = 'diff-index' - extra_args = [] - if len(commits) == 2: - git_tool = 'diff-tree' - if diff_common_commit: - commits = [f'{commits[0]}...{commits[1]}'] - elif staged: - extra_args += ['--cached'] - - cmd = ['git', git_tool, '-p', '-U0'] + extra_args + commits + ['--'] - cmd.extend(files) - p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) - p.stdin.close() - return p + """Return a subprocess object producing the diff from `commits`. + + The return value's `stdin` file object will produce a patch with the + differences between the working directory (or stage if --staged is used) and + the first commit if a single one was specified, or the difference between + both specified commits, filtered on `files` (if non-empty). + Zero context lines are used in the patch.""" + git_tool = "diff-index" + extra_args = [] + if len(commits) == 2: + git_tool = "diff-tree" + if diff_common_commit: + commits = [f"{commits[0]}...{commits[1]}"] + elif staged: + extra_args += ["--cached"] + + cmd = ["git", git_tool, "-p", "-U0"] + extra_args + commits + ["--"] + cmd.extend(files) + p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + p.stdin.close() + return p def extract_lines(patch_file): - """Extract the changed lines in `patch_file`. - - The return value is a dictionary mapping filename to a list of (start_line, - line_count) pairs. - - The input must have been produced with ``-U0``, meaning unidiff format with - zero lines of context. The return value is a dict mapping filename to a - list of line `Range`s.""" - matches = {} - for line in patch_file: - line = convert_string(line) - match = re.search(r'^\+\+\+\ [^/]+/(.*)', line) - if match: - filename = match.group(1).rstrip('\r\n\t') - match = re.search(r'^@@ -[0-9,]+ \+(\d+)(,(\d+))?', line) - if match: - start_line = int(match.group(1)) - line_count = 1 - if match.group(3): - line_count = int(match.group(3)) - if line_count == 0: - line_count = 1 - if start_line == 0: - continue - matches.setdefault(filename, []).append(Range(start_line, line_count)) - return matches + """Extract the changed lines in `patch_file`. + + The return value is a dictionary mapping filename to a list of (start_line, + line_count) pairs. + + The input must have been produced with ``-U0``, meaning unidiff format with + zero lines of context. The return value is a dict mapping filename to a + list of line `Range`s.""" + matches = {} + for line in patch_file: + line = convert_string(line) + match = re.search(r"^\+\+\+\ [^/]+/(.*)", line) + if match: + filename = match.group(1).rstrip("\r\n\t") + match = re.search(r"^@@ -[0-9,]+ \+(\d+)(,(\d+))?", line) + if match: + start_line = int(match.group(1)) + line_count = 1 + if match.group(3): + line_count = int(match.group(3)) + if line_count == 0: + line_count = 1 + if start_line == 0: + continue + matches.setdefault(filename, []).append( + Range(start_line, line_count) + ) + return matches def filter_by_extension(dictionary, allowed_extensions): - """Delete every key in `dictionary` that doesn't have an allowed extension. + """Delete every key in `dictionary` that doesn't have an allowed extension. - `allowed_extensions` must be a collection of lowercase file extensions, - excluding the period.""" - allowed_extensions = frozenset(allowed_extensions) - for filename in list(dictionary.keys()): - base_ext = filename.rsplit('.', 1) - if len(base_ext) == 1 and '' in allowed_extensions: - continue - if len(base_ext) == 1 or base_ext[1].lower() not in allowed_extensions: - del dictionary[filename] + `allowed_extensions` must be a collection of lowercase file extensions, + excluding the period.""" + allowed_extensions = frozenset(allowed_extensions) + for filename in list(dictionary.keys()): + base_ext = filename.rsplit(".", 1) + if len(base_ext) == 1 and "" in allowed_extensions: + continue + if len(base_ext) == 1 or base_ext[1].lower() not in allowed_extensions: + del dictionary[filename] def filter_symlinks(dictionary): - """Delete every key in `dictionary` that is a symlink.""" - for filename in list(dictionary.keys()): - if os.path.islink(filename): - del dictionary[filename] + """Delete every key in `dictionary` that is a symlink.""" + for filename in list(dictionary.keys()): + if os.path.islink(filename): + del dictionary[filename] def filter_ignored_files(dictionary, binary): - """Delete every key in `dictionary` that is ignored by clang-format.""" - ignored_files = run(binary, '-list-ignored', *dictionary.keys()) - if not ignored_files: - return - ignored_files = ignored_files.split('\n') - for filename in ignored_files: - del dictionary[filename] + """Delete every key in `dictionary` that is ignored by clang-format.""" + ignored_files = run(binary, "-list-ignored", *dictionary.keys()) + if not ignored_files: + return + ignored_files = ignored_files.split("\n") + for filename in ignored_files: + del dictionary[filename] def cd_to_toplevel(): - """Change to the top level of the git repository.""" - toplevel = run('git', 'rev-parse', '--show-toplevel') - os.chdir(toplevel) + """Change to the top level of the git repository.""" + toplevel = run("git", "rev-parse", "--show-toplevel") + os.chdir(toplevel) def create_tree_from_workdir(filenames): - """Create a new git tree with the given files from the working directory. + """Create a new git tree with the given files from the working directory. - Returns the object ID (SHA-1) of the created tree.""" - return create_tree(filenames, '--stdin') + Returns the object ID (SHA-1) of the created tree.""" + return create_tree(filenames, "--stdin") def create_tree_from_index(filenames): - # Copy the environment, because the files have to be read from the original - # index. - env = os.environ.copy() - def index_contents_generator(): - for filename in filenames: - git_ls_files_cmd = ['git', 'ls-files', '--stage', '-z', '--', filename] - git_ls_files = subprocess.Popen(git_ls_files_cmd, env=env, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE) - stdout = git_ls_files.communicate()[0] - yield convert_string(stdout.split(b'\0')[0]) - return create_tree(index_contents_generator(), '--index-info') - - -def run_clang_format_and_save_to_tree(changed_lines, revision=None, - binary='clang-format', style=None): - """Run clang-format on each file and save the result to a git tree. - - Returns the object ID (SHA-1) of the created tree.""" - # Copy the environment when formatting the files in the index, because the - # files have to be read from the original index. - env = os.environ.copy() if revision == '' else None - def iteritems(container): - try: - return container.iteritems() # Python 2 - except AttributeError: - return container.items() # Python 3 - def index_info_generator(): - for filename, line_ranges in iteritems(changed_lines): - if revision is not None: - if len(revision) > 0: - git_metadata_cmd = ['git', 'ls-tree', - '%s:%s' % (revision, os.path.dirname(filename)), - os.path.basename(filename)] - else: - git_metadata_cmd = ['git', 'ls-files', '--stage', '--', filename] - git_metadata = subprocess.Popen(git_metadata_cmd, env=env, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE) - stdout = git_metadata.communicate()[0] - mode = oct(int(stdout.split()[0], 8)) - else: - mode = oct(os.stat(filename).st_mode) - # Adjust python3 octal format so that it matches what git expects - if mode.startswith('0o'): - mode = '0' + mode[2:] - blob_id = clang_format_to_blob(filename, line_ranges, - revision=revision, - binary=binary, - style=style, - env=env) - yield '%s %s\t%s' % (mode, blob_id, filename) - return create_tree(index_info_generator(), '--index-info') + # Copy the environment, because the files have to be read from the original + # index. + env = os.environ.copy() + + def index_contents_generator(): + for filename in filenames: + git_ls_files_cmd = [ + "git", + "ls-files", + "--stage", + "-z", + "--", + filename, + ] + git_ls_files = subprocess.Popen( + git_ls_files_cmd, + env=env, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + ) + stdout = git_ls_files.communicate()[0] + yield convert_string(stdout.split(b"\0")[0]) + + return create_tree(index_contents_generator(), "--index-info") + + +def run_clang_format_and_save_to_tree( + changed_lines, revision=None, binary="clang-format", style=None +): + """Run clang-format on each file and save the result to a git tree. + + Returns the object ID (SHA-1) of the created tree.""" + # Copy the environment when formatting the files in the index, because the + # files have to be read from the original index. + env = os.environ.copy() if revision == "" else None + + def iteritems(container): + try: + return container.iteritems() # Python 2 + except AttributeError: + return container.items() # Python 3 + + def index_info_generator(): + for filename, line_ranges in iteritems(changed_lines): + if revision is not None: + if len(revision) > 0: + git_metadata_cmd = [ + "git", + "ls-tree", + "%s:%s" % (revision, os.path.dirname(filename)), + os.path.basename(filename), + ] + else: + git_metadata_cmd = [ + "git", + "ls-files", + "--stage", + "--", + filename, + ] + git_metadata = subprocess.Popen( + git_metadata_cmd, + env=env, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + ) + stdout = git_metadata.communicate()[0] + mode = oct(int(stdout.split()[0], 8)) + else: + mode = oct(os.stat(filename).st_mode) + # Adjust python3 octal format so that it matches what git expects + if mode.startswith("0o"): + mode = "0" + mode[2:] + blob_id = clang_format_to_blob( + filename, + line_ranges, + revision=revision, + binary=binary, + style=style, + env=env, + ) + yield "%s %s\t%s" % (mode, blob_id, filename) + + return create_tree(index_info_generator(), "--index-info") def create_tree(input_lines, mode): - """Create a tree object from the given input. - - If mode is '--stdin', it must be a list of filenames. If mode is - '--index-info' is must be a list of values suitable for "git update-index - --index-info", such as " ". Any other mode - is invalid.""" - assert mode in ('--stdin', '--index-info') - cmd = ['git', 'update-index', '--add', '-z', mode] - with temporary_index_file(): - p = subprocess.Popen(cmd, stdin=subprocess.PIPE) - for line in input_lines: - p.stdin.write(to_bytes('%s\0' % line)) - p.stdin.close() - if p.wait() != 0: - die('`%s` failed' % ' '.join(cmd)) - tree_id = run('git', 'write-tree') - return tree_id - - -def clang_format_to_blob(filename, line_ranges, revision=None, - binary='clang-format', style=None, env=None): - """Run clang-format on the given file and save the result to a git blob. - - Runs on the file in `revision` if not None, or on the file in the working - directory if `revision` is None. Revision can be set to an empty string to run - clang-format on the file in the index. - - Returns the object ID (SHA-1) of the created blob.""" - clang_format_cmd = [binary] - if style: - clang_format_cmd.extend(['--style='+style]) - clang_format_cmd.extend([ - '--lines=%s:%s' % (start_line, start_line+line_count-1) - for start_line, line_count in line_ranges]) - if revision is not None: - clang_format_cmd.extend(['--assume-filename='+filename]) - git_show_cmd = ['git', 'cat-file', 'blob', '%s:%s' % (revision, filename)] - git_show = subprocess.Popen(git_show_cmd, env=env, stdin=subprocess.PIPE, - stdout=subprocess.PIPE) - git_show.stdin.close() - clang_format_stdin = git_show.stdout - else: - clang_format_cmd.extend([filename]) - git_show = None - clang_format_stdin = subprocess.PIPE - try: - clang_format = subprocess.Popen(clang_format_cmd, stdin=clang_format_stdin, - stdout=subprocess.PIPE) - if clang_format_stdin == subprocess.PIPE: - clang_format_stdin = clang_format.stdin - except OSError as e: - if e.errno == errno.ENOENT: - die('cannot find executable "%s"' % binary) + """Create a tree object from the given input. + + If mode is '--stdin', it must be a list of filenames. If mode is + '--index-info' is must be a list of values suitable for "git update-index + --index-info", such as " ". Any other + mode is invalid.""" + assert mode in ("--stdin", "--index-info") + cmd = ["git", "update-index", "--add", "-z", mode] + with temporary_index_file(): + p = subprocess.Popen(cmd, stdin=subprocess.PIPE) + for line in input_lines: + p.stdin.write(to_bytes("%s\0" % line)) + p.stdin.close() + if p.wait() != 0: + die("`%s` failed" % " ".join(cmd)) + tree_id = run("git", "write-tree") + return tree_id + + +def clang_format_to_blob( + filename, + line_ranges, + revision=None, + binary="clang-format", + style=None, + env=None, +): + """Run clang-format on the given file and save the result to a git blob. + + Runs on the file in `revision` if not None, or on the file in the working + directory if `revision` is None. Revision can be set to an empty string to + run clang-format on the file in the index. + + Returns the object ID (SHA-1) of the created blob.""" + clang_format_cmd = [binary] + if style: + clang_format_cmd.extend(["--style=" + style]) + clang_format_cmd.extend( + [ + "--lines=%s:%s" % (start_line, start_line + line_count - 1) + for start_line, line_count in line_ranges + ] + ) + if revision is not None: + clang_format_cmd.extend(["--assume-filename=" + filename]) + git_show_cmd = [ + "git", + "cat-file", + "blob", + "%s:%s" % (revision, filename), + ] + git_show = subprocess.Popen( + git_show_cmd, env=env, stdin=subprocess.PIPE, stdout=subprocess.PIPE + ) + git_show.stdin.close() + clang_format_stdin = git_show.stdout else: - raise - clang_format_stdin.close() - hash_object_cmd = ['git', 'hash-object', '-w', '--path='+filename, '--stdin'] - hash_object = subprocess.Popen(hash_object_cmd, stdin=clang_format.stdout, - stdout=subprocess.PIPE) - clang_format.stdout.close() - stdout = hash_object.communicate()[0] - if hash_object.returncode != 0: - die('`%s` failed' % ' '.join(hash_object_cmd)) - if clang_format.wait() != 0: - die('`%s` failed' % ' '.join(clang_format_cmd)) - if git_show and git_show.wait() != 0: - die('`%s` failed' % ' '.join(git_show_cmd)) - return convert_string(stdout).rstrip('\r\n') + clang_format_cmd.extend([filename]) + git_show = None + clang_format_stdin = subprocess.PIPE + try: + clang_format = subprocess.Popen( + clang_format_cmd, stdin=clang_format_stdin, stdout=subprocess.PIPE + ) + if clang_format_stdin == subprocess.PIPE: + clang_format_stdin = clang_format.stdin + except OSError as e: + if e.errno == errno.ENOENT: + die('cannot find executable "%s"' % binary) + else: + raise + clang_format_stdin.close() + hash_object_cmd = [ + "git", + "hash-object", + "-w", + "--path=" + filename, + "--stdin", + ] + hash_object = subprocess.Popen( + hash_object_cmd, stdin=clang_format.stdout, stdout=subprocess.PIPE + ) + clang_format.stdout.close() + stdout = hash_object.communicate()[0] + if hash_object.returncode != 0: + die("`%s` failed" % " ".join(hash_object_cmd)) + if clang_format.wait() != 0: + die("`%s` failed" % " ".join(clang_format_cmd)) + if git_show and git_show.wait() != 0: + die("`%s` failed" % " ".join(git_show_cmd)) + return convert_string(stdout).rstrip("\r\n") @contextlib.contextmanager def temporary_index_file(tree=None): - """Context manager for setting GIT_INDEX_FILE to a temporary file and deleting - the file afterward.""" - index_path = create_temporary_index(tree) - old_index_path = os.environ.get('GIT_INDEX_FILE') - os.environ['GIT_INDEX_FILE'] = index_path - try: - yield - finally: - if old_index_path is None: - del os.environ['GIT_INDEX_FILE'] - else: - os.environ['GIT_INDEX_FILE'] = old_index_path - os.remove(index_path) + """Context manager for setting GIT_INDEX_FILE to a temporary file and + deleting the file afterward.""" + index_path = create_temporary_index(tree) + old_index_path = os.environ.get("GIT_INDEX_FILE") + os.environ["GIT_INDEX_FILE"] = index_path + try: + yield + finally: + if old_index_path is None: + del os.environ["GIT_INDEX_FILE"] + else: + os.environ["GIT_INDEX_FILE"] = old_index_path + os.remove(index_path) def create_temporary_index(tree=None): - """Create a temporary index file and return the created file's path. + """Create a temporary index file and return the created file's path. - If `tree` is not None, use that as the tree to read in. Otherwise, an - empty index is created.""" - gitdir = run('git', 'rev-parse', '--git-dir') - path = os.path.join(gitdir, temp_index_basename) - if tree is None: - tree = '--empty' - run('git', 'read-tree', '--index-output='+path, tree) - return path + If `tree` is not None, use that as the tree to read in. Otherwise, an + empty index is created.""" + gitdir = run("git", "rev-parse", "--git-dir") + path = os.path.join(gitdir, temp_index_basename) + if tree is None: + tree = "--empty" + run("git", "read-tree", "--index-output=" + path, tree) + return path def print_diff(old_tree, new_tree): - """Print the diff between the two trees to stdout.""" - # We use the porcelain 'diff' and not plumbing 'diff-tree' because the output - # is expected to be viewed by the user, and only the former does nice things - # like color and pagination. - # - # We also only print modified files since `new_tree` only contains the files - # that were modified, so unmodified files would show as deleted without the - # filter. - return subprocess.run(['git', 'diff', '--diff-filter=M', - '--exit-code', old_tree, new_tree]).returncode + """Print the diff between the two trees to stdout.""" + # We use the porcelain 'diff' and not plumbing 'diff-tree' because the + # output is expected to be viewed by the user, and only the former does nice + # things like color and pagination. + # + # We also only print modified files since `new_tree` only contains the files + # that were modified, so unmodified files would show as deleted without the + # filter. + return subprocess.run( + ["git", "diff", "--diff-filter=M", "--exit-code", old_tree, new_tree] + ).returncode + def print_diffstat(old_tree, new_tree): - """Print the diffstat between the two trees to stdout.""" - # We use the porcelain 'diff' and not plumbing 'diff-tree' because the output - # is expected to be viewed by the user, and only the former does nice things - # like color and pagination. - # - # We also only print modified files since `new_tree` only contains the files - # that were modified, so unmodified files would show as deleted without the - # filter. - return subprocess.run(['git', 'diff', '--diff-filter=M', '--exit-code', - '--stat', old_tree, new_tree]).returncode + """Print the diffstat between the two trees to stdout.""" + # We use the porcelain 'diff' and not plumbing 'diff-tree' because the + # output is expected to be viewed by the user, and only the former does nice + # things like color and pagination. + # + # We also only print modified files since `new_tree` only contains the files + # that were modified, so unmodified files would show as deleted without the + # filter. + return subprocess.run( + [ + "git", + "diff", + "--diff-filter=M", + "--exit-code", + "--stat", + old_tree, + new_tree, + ] + ).returncode + def apply_changes(old_tree, new_tree, force=False, patch_mode=False): - """Apply the changes in `new_tree` to the working directory. - - Bails if there are local changes in those files and not `force`. If - `patch_mode`, runs `git checkout --patch` to select hunks interactively.""" - changed_files = run('git', 'diff-tree', '--diff-filter=M', '-r', '-z', - '--name-only', old_tree, - new_tree).rstrip('\0').split('\0') - if not force: - unstaged_files = run('git', 'diff-files', '--name-status', *changed_files) - if unstaged_files: - print('The following files would be modified but ' - 'have unstaged changes:', file=sys.stderr) - print(unstaged_files, file=sys.stderr) - print('Please commit, stage, or stash them first.', file=sys.stderr) - sys.exit(2) - if patch_mode: - # In patch mode, we could just as well create an index from the new tree - # and checkout from that, but then the user will be presented with a - # message saying "Discard ... from worktree". Instead, we use the old - # tree as the index and checkout from new_tree, which gives the slightly - # better message, "Apply ... to index and worktree". This is not quite - # right, since it won't be applied to the user's index, but oh well. - with temporary_index_file(old_tree): - subprocess.run(['git', 'checkout', '--patch', new_tree], check=True) - index_tree = old_tree - else: - with temporary_index_file(new_tree): - run('git', 'checkout-index', '-f', '--', *changed_files) - return changed_files + """Apply the changes in `new_tree` to the working directory. + + Bails if there are local changes in those files and not `force`. If + `patch_mode`, runs `git checkout --patch` to select hunks interactively.""" + changed_files = ( + run( + "git", + "diff-tree", + "--diff-filter=M", + "-r", + "-z", + "--name-only", + old_tree, + new_tree, + ) + .rstrip("\0") + .split("\0") + ) + if not force: + unstaged_files = run( + "git", "diff-files", "--name-status", *changed_files + ) + if unstaged_files: + print( + "The following files would be modified but have unstaged " + "changes:", + file=sys.stderr, + ) + print(unstaged_files, file=sys.stderr) + print("Please commit, stage, or stash them first.", file=sys.stderr) + sys.exit(2) + if patch_mode: + # In patch mode, we could just as well create an index from the new tree + # and checkout from that, but then the user will be presented with a + # message saying "Discard ... from worktree". Instead, we use the old + # tree as the index and checkout from new_tree, which gives the slightly + # better message, "Apply ... to index and worktree". This is not quite + # right, since it won't be applied to the user's index, but oh well. + with temporary_index_file(old_tree): + subprocess.run(["git", "checkout", "--patch", new_tree], check=True) + index_tree = old_tree + else: + with temporary_index_file(new_tree): + run("git", "checkout-index", "-f", "--", *changed_files) + return changed_files def run(*args, **kwargs): - stdin = kwargs.pop('stdin', '') - verbose = kwargs.pop('verbose', True) - strip = kwargs.pop('strip', True) - for name in kwargs: - raise TypeError("run() got an unexpected keyword argument '%s'" % name) - p = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - stdin=subprocess.PIPE) - stdout, stderr = p.communicate(input=stdin) - - stdout = convert_string(stdout) - stderr = convert_string(stderr) - - if p.returncode == 0: + stdin = kwargs.pop("stdin", "") + verbose = kwargs.pop("verbose", True) + strip = kwargs.pop("strip", True) + for name in kwargs: + raise TypeError("run() got an unexpected keyword argument '%s'" % name) + p = subprocess.Popen( + args, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + stdin=subprocess.PIPE, + ) + stdout, stderr = p.communicate(input=stdin) + + stdout = convert_string(stdout) + stderr = convert_string(stderr) + + if p.returncode == 0: + if stderr: + if verbose: + print( + "`%s` printed to stderr:" % " ".join(args), file=sys.stderr + ) + print(stderr.rstrip(), file=sys.stderr) + if strip: + stdout = stdout.rstrip("\r\n") + return stdout + if verbose: + print( + "`%s` returned %s" % (" ".join(args), p.returncode), file=sys.stderr + ) if stderr: - if verbose: - print('`%s` printed to stderr:' % ' '.join(args), file=sys.stderr) - print(stderr.rstrip(), file=sys.stderr) - if strip: - stdout = stdout.rstrip('\r\n') - return stdout - if verbose: - print('`%s` returned %s' % (' '.join(args), p.returncode), file=sys.stderr) - if stderr: - print(stderr.rstrip(), file=sys.stderr) - sys.exit(2) + print(stderr.rstrip(), file=sys.stderr) + sys.exit(2) def die(message): - print('error:', message, file=sys.stderr) - sys.exit(2) + print("error:", message, file=sys.stderr) + sys.exit(2) def to_bytes(str_input): # Encode to UTF-8 to get binary data. if isinstance(str_input, bytes): return str_input - return str_input.encode('utf-8') + return str_input.encode("utf-8") def to_string(bytes_input): if isinstance(bytes_input, str): return bytes_input - return bytes_input.encode('utf-8') + return bytes_input.encode("utf-8") def convert_string(bytes_input): try: - return to_string(bytes_input.decode('utf-8')) - except AttributeError: # 'str' object has no attribute 'decode'. + return to_string(bytes_input.decode("utf-8")) + except AttributeError: # 'str' object has no attribute 'decode'. return str(bytes_input) except UnicodeError: return str(bytes_input) -if __name__ == '__main__': - sys.exit(main()) + +if __name__ == "__main__": + sys.exit(main()) diff --git a/clang/tools/clang-installapi/Options.cpp b/clang/tools/clang-installapi/Options.cpp index 3fa79636de5d7..8a2c3463189fa 100644 --- a/clang/tools/clang-installapi/Options.cpp +++ b/clang/tools/clang-installapi/Options.cpp @@ -31,41 +31,21 @@ namespace drv = clang::driver::options; namespace clang { namespace installapi { -/// Create prefix string literals used in InstallAPIOpts.td. -#define PREFIX(NAME, VALUE) \ - static constexpr llvm::StringLiteral NAME##_init[] = VALUE; \ - static constexpr llvm::ArrayRef NAME( \ - NAME##_init, std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "InstallAPIOpts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE -static constexpr const llvm::StringLiteral PrefixTable_init[] = -#define PREFIX_UNION(VALUES) VALUES +#define OPTTABLE_PREFIXES_TABLE_CODE #include "InstallAPIOpts.inc" -#undef PREFIX_UNION - ; -static constexpr const ArrayRef - PrefixTable(PrefixTable_init, std::size(PrefixTable_init) - 1); +#undef OPTTABLE_PREFIXES_TABLE_CODE + +#define OPTTABLE_PREFIXES_UNION_CODE +#include "InstallAPIOpts.inc" +#undef OPTTABLE_PREFIXES_UNION_CODE /// Create table mapping all options defined in InstallAPIOpts.td. static constexpr OptTable::Info InfoTable[] = { -#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \ - VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, \ - VALUES) \ - {PREFIX, \ - NAME, \ - HELPTEXT, \ - HELPTEXTSFORVARIANTS, \ - METAVAR, \ - OPT_##ID, \ - Option::KIND##Class, \ - PARAM, \ - FLAGS, \ - VISIBILITY, \ - OPT_##GROUP, \ - OPT_##ALIAS, \ - ALIASARGS, \ - VALUES}, +#define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), #include "InstallAPIOpts.inc" #undef OPTION }; @@ -75,7 +55,9 @@ namespace { /// \brief Create OptTable class for parsing actual command line arguments. class DriverOptTable : public opt::PrecomputedOptTable { public: - DriverOptTable() : PrecomputedOptTable(InfoTable, PrefixTable) {} + DriverOptTable() + : PrecomputedOptTable(OptionStrTable, OptionPrefixesTable, InfoTable, + OptionPrefixesUnion) {} }; } // end anonymous namespace. diff --git a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp index ebafd7eb7774e..fae32a3503c18 100644 --- a/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp +++ b/clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp @@ -174,12 +174,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "LinkerWrapperOpts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "LinkerWrapperOpts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -189,7 +190,8 @@ static constexpr OptTable::Info InfoTable[] = { class WrapperOptTable : public opt::GenericOptTable { public: - WrapperOptTable() : opt::GenericOptTable(InfoTable) {} + WrapperOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {} }; const OptTable &getOptTable() { diff --git a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp index bc191afdca739..faf73a7c2f193 100644 --- a/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp +++ b/clang/tools/clang-nvlink-wrapper/ClangNVLinkWrapper.cpp @@ -109,12 +109,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "NVLinkOpts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "NVLinkOpts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -124,7 +125,8 @@ static constexpr OptTable::Info InfoTable[] = { class WrapperOptTable : public opt::GenericOptTable { public: - WrapperOptTable() : opt::GenericOptTable(InfoTable) {} + WrapperOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {} }; const OptTable &getOptTable() { diff --git a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp index 0189fe5d56ab2..14c584064e311 100644 --- a/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp +++ b/clang/tools/clang-offload-bundler/ClangOffloadBundler.cpp @@ -196,13 +196,14 @@ int main(int argc, const char **argv) { auto reportError = [argv](Error E) { logAllUnhandledErrors(std::move(E), WithColor::error(errs(), argv[0])); - exit(1); + return 1; }; auto doWork = [&](std::function Work) { if (llvm::Error Err = Work()) { - reportError(std::move(Err)); + return reportError(std::move(Err)); } + return 0; }; auto warningOS = [argv]() -> raw_ostream & { @@ -223,14 +224,14 @@ int main(int argc, const char **argv) { if (!Objcopy) Objcopy = sys::findProgramByName("llvm-objcopy"); if (!Objcopy) - reportError(createStringError(Objcopy.getError(), - "unable to find 'llvm-objcopy' in path")); + return reportError(createStringError( + Objcopy.getError(), "unable to find 'llvm-objcopy' in path")); else BundlerConfig.ObjcopyPath = *Objcopy; if (InputFileNames.getNumOccurrences() != 0 && InputFileNamesDeprecatedOpt.getNumOccurrences() != 0) { - reportError(createStringError( + return reportError(createStringError( errc::invalid_argument, "-inputs and -input cannot be used together, use only -input instead")); } @@ -246,9 +247,9 @@ int main(int argc, const char **argv) { if (OutputFileNames.getNumOccurrences() != 0 && OutputFileNamesDeprecatedOpt.getNumOccurrences() != 0) { - reportError(createStringError(errc::invalid_argument, - "-outputs and -output cannot be used " - "together, use only -output instead")); + return reportError(createStringError(errc::invalid_argument, + "-outputs and -output cannot be used " + "together, use only -output instead")); } if (OutputFileNamesDeprecatedOpt.size()) { @@ -262,77 +263,77 @@ int main(int argc, const char **argv) { if (ListBundleIDs) { if (Unbundle) { - reportError( + return reportError( createStringError(errc::invalid_argument, "-unbundle and -list cannot be used together")); } if (InputFileNames.size() != 1) { - reportError(createStringError(errc::invalid_argument, - "only one input file supported for -list")); + return reportError(createStringError( + errc::invalid_argument, "only one input file supported for -list")); } if (OutputFileNames.size()) { - reportError(createStringError(errc::invalid_argument, - "-outputs option is invalid for -list")); + return reportError(createStringError( + errc::invalid_argument, "-outputs option is invalid for -list")); } if (TargetNames.size()) { - reportError(createStringError(errc::invalid_argument, - "-targets option is invalid for -list")); + return reportError(createStringError( + errc::invalid_argument, "-targets option is invalid for -list")); } - doWork([&]() { return OffloadBundler::ListBundleIDsInFile( - InputFileNames.front(), - BundlerConfig); }); - return 0; + return doWork([&]() { + return OffloadBundler::ListBundleIDsInFile(InputFileNames.front(), + BundlerConfig); + }); } if (BundlerConfig.CheckInputArchive) { if (!Unbundle) { - reportError(createStringError(errc::invalid_argument, - "-check-input-archive cannot be used while " - "bundling")); + return reportError(createStringError( + errc::invalid_argument, "-check-input-archive cannot be used while " + "bundling")); } if (Unbundle && BundlerConfig.FilesType != "a") { - reportError(createStringError(errc::invalid_argument, - "-check-input-archive can only be used for " - "unbundling archives (-type=a)")); + return reportError(createStringError( + errc::invalid_argument, "-check-input-archive can only be used for " + "unbundling archives (-type=a)")); } } if (OutputFileNames.size() == 0) { - reportError( + return reportError( createStringError(errc::invalid_argument, "no output file specified!")); } if (TargetNames.getNumOccurrences() == 0) { - reportError(createStringError( + return reportError(createStringError( errc::invalid_argument, "for the --targets option: must be specified at least once!")); } if (Unbundle) { if (InputFileNames.size() != 1) { - reportError(createStringError( + return reportError(createStringError( errc::invalid_argument, "only one input file supported in unbundling mode")); } if (OutputFileNames.size() != TargetNames.size()) { - reportError(createStringError(errc::invalid_argument, - "number of output files and targets should " - "match in unbundling mode")); + return reportError(createStringError( + errc::invalid_argument, "number of output files and targets should " + "match in unbundling mode")); } } else { if (BundlerConfig.FilesType == "a") { - reportError(createStringError(errc::invalid_argument, - "Archive files are only supported " - "for unbundling")); + return reportError(createStringError(errc::invalid_argument, + "Archive files are only supported " + "for unbundling")); } if (OutputFileNames.size() != 1) { - reportError(createStringError( - errc::invalid_argument, - "only one output file supported in bundling mode")); + return reportError( + createStringError(errc::invalid_argument, + "only one output file supported in bundling mode")); } if (InputFileNames.size() != TargetNames.size()) { - reportError(createStringError( + return reportError(createStringError( errc::invalid_argument, "number of input files and targets should match in bundling mode")); } @@ -350,8 +351,8 @@ int main(int argc, const char **argv) { std::vector StandardizedTargetNames; for (StringRef Target : TargetNames) { if (!ParsedTargets.insert(Target).second) { - reportError(createStringError(errc::invalid_argument, - "Duplicate targets are not allowed")); + return reportError(createStringError( + errc::invalid_argument, "Duplicate targets are not allowed")); } auto OffloadInfo = OffloadTargetInfo(Target, BundlerConfig); @@ -368,7 +369,7 @@ int main(int argc, const char **argv) { Msg << ", unknown offloading kind '" << OffloadInfo.OffloadKind << "'"; if (!TripleIsValid) Msg << ", unknown target triple '" << OffloadInfo.Triple.str() << "'"; - reportError(createStringError(errc::invalid_argument, Msg.str())); + return reportError(createStringError(errc::invalid_argument, Msg.str())); } TargetIDs[OffloadInfo.OffloadKind.str() + "-" + OffloadInfo.Triple.str()] @@ -395,7 +396,7 @@ int main(int argc, const char **argv) { Msg << "Cannot bundle inputs with conflicting targets: '" << TargetID.first + "-" + ConflictingTID->first << "' and '" << TargetID.first + "-" + ConflictingTID->second << "'"; - reportError(createStringError(errc::invalid_argument, Msg.str())); + return reportError(createStringError(errc::invalid_argument, Msg.str())); } } @@ -408,14 +409,14 @@ int main(int argc, const char **argv) { // treat missing host triple as error if we do unbundling. if ((Unbundle && HostTargetNum > 1) || (!Unbundle && HostTargetNum != 1 && !BundlerConfig.AllowNoHost)) { - reportError(createStringError(errc::invalid_argument, - "expecting exactly one host target but got " + - Twine(HostTargetNum))); + return reportError(createStringError( + errc::invalid_argument, + "expecting exactly one host target but got " + Twine(HostTargetNum))); } OffloadBundler Bundler(BundlerConfig); - doWork([&]() { + return doWork([&]() { if (Unbundle) { if (BundlerConfig.FilesType == "a") return Bundler.UnbundleArchive(); @@ -424,5 +425,4 @@ int main(int argc, const char **argv) { } else return Bundler.BundleFiles(); }); - return 0; } diff --git a/clang/tools/clang-scan-deps/ClangScanDeps.cpp b/clang/tools/clang-scan-deps/ClangScanDeps.cpp index 58b56dcfd3bec..bd36181fca3f3 100644 --- a/clang/tools/clang-scan-deps/ClangScanDeps.cpp +++ b/clang/tools/clang-scan-deps/ClangScanDeps.cpp @@ -50,12 +50,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - constexpr llvm::StringLiteral NAME##_init[] = VALUE; \ - constexpr llvm::ArrayRef NAME( \ - NAME##_init, std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "Opts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "Opts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE const llvm::opt::OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -65,7 +66,8 @@ const llvm::opt::OptTable::Info InfoTable[] = { class ScanDepsOptTable : public llvm::opt::GenericOptTable { public: - ScanDepsOptTable() : GenericOptTable(InfoTable) { + ScanDepsOptTable() + : GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) { setGroupedShortOptions(true); } }; diff --git a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp index 076458a275d98..2bcb3757d49d0 100644 --- a/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp +++ b/clang/tools/clang-sycl-linker/ClangSYCLLinker.cpp @@ -88,12 +88,13 @@ enum ID { #undef OPTION }; -#define PREFIX(NAME, VALUE) \ - static constexpr StringLiteral NAME##_init[] = VALUE; \ - static constexpr ArrayRef NAME(NAME##_init, \ - std::size(NAME##_init) - 1); +#define OPTTABLE_STR_TABLE_CODE #include "SYCLLinkOpts.inc" -#undef PREFIX +#undef OPTTABLE_STR_TABLE_CODE + +#define OPTTABLE_PREFIXES_TABLE_CODE +#include "SYCLLinkOpts.inc" +#undef OPTTABLE_PREFIXES_TABLE_CODE static constexpr OptTable::Info InfoTable[] = { #define OPTION(...) LLVM_CONSTRUCT_OPT_INFO(__VA_ARGS__), @@ -103,7 +104,8 @@ static constexpr OptTable::Info InfoTable[] = { class LinkerOptTable : public opt::GenericOptTable { public: - LinkerOptTable() : opt::GenericOptTable(InfoTable) {} + LinkerOptTable() + : opt::GenericOptTable(OptionStrTable, OptionPrefixesTable, InfoTable) {} }; const OptTable &getOptTable() { diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp index def4524449355..701582138e053 100644 --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -2185,6 +2185,10 @@ class EnqueueVisitor : public ConstStmtVisitor, void VisitOpenACCComputeConstruct(const OpenACCComputeConstruct *D); void VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *D); void VisitOpenACCCombinedConstruct(const OpenACCCombinedConstruct *D); + void VisitOpenACCDataConstruct(const OpenACCDataConstruct *D); + void VisitOpenACCEnterDataConstruct(const OpenACCEnterDataConstruct *D); + void VisitOpenACCExitDataConstruct(const OpenACCExitDataConstruct *D); + void VisitOpenACCHostDataConstruct(const OpenACCHostDataConstruct *D); void VisitOMPExecutableDirective(const OMPExecutableDirective *D); void VisitOMPLoopBasedDirective(const OMPLoopBasedDirective *D); void VisitOMPLoopDirective(const OMPLoopDirective *D); @@ -2882,6 +2886,19 @@ void OpenACCClauseEnqueue::VisitCreateClause(const OpenACCCreateClause &C) { void OpenACCClauseEnqueue::VisitAttachClause(const OpenACCAttachClause &C) { VisitVarList(C); } + +void OpenACCClauseEnqueue::VisitDetachClause(const OpenACCDetachClause &C) { + VisitVarList(C); +} +void OpenACCClauseEnqueue::VisitDeleteClause(const OpenACCDeleteClause &C) { + VisitVarList(C); +} + +void OpenACCClauseEnqueue::VisitUseDeviceClause( + const OpenACCUseDeviceClause &C) { + VisitVarList(C); +} + void OpenACCClauseEnqueue::VisitDevicePtrClause( const OpenACCDevicePtrClause &C) { VisitVarList(C); @@ -2917,6 +2934,10 @@ void OpenACCClauseEnqueue::VisitAutoClause(const OpenACCAutoClause &C) {} void OpenACCClauseEnqueue::VisitIndependentClause( const OpenACCIndependentClause &C) {} void OpenACCClauseEnqueue::VisitSeqClause(const OpenACCSeqClause &C) {} +void OpenACCClauseEnqueue::VisitFinalizeClause(const OpenACCFinalizeClause &C) { +} +void OpenACCClauseEnqueue::VisitIfPresentClause( + const OpenACCIfPresentClause &C) {} void OpenACCClauseEnqueue::VisitCollapseClause(const OpenACCCollapseClause &C) { Visitor.AddStmt(C.getLoopCount()); } @@ -3587,6 +3608,29 @@ void EnqueueVisitor::VisitOpenACCCombinedConstruct( for (auto *Clause : C->clauses()) EnqueueChildren(Clause); } +void EnqueueVisitor::VisitOpenACCDataConstruct(const OpenACCDataConstruct *C) { + EnqueueChildren(C); + for (auto *Clause : C->clauses()) + EnqueueChildren(Clause); +} +void EnqueueVisitor::VisitOpenACCEnterDataConstruct( + const OpenACCEnterDataConstruct *C) { + EnqueueChildren(C); + for (auto *Clause : C->clauses()) + EnqueueChildren(Clause); +} +void EnqueueVisitor::VisitOpenACCExitDataConstruct( + const OpenACCExitDataConstruct *C) { + EnqueueChildren(C); + for (auto *Clause : C->clauses()) + EnqueueChildren(Clause); +} +void EnqueueVisitor::VisitOpenACCHostDataConstruct( + const OpenACCHostDataConstruct *C) { + EnqueueChildren(C); + for (auto *Clause : C->clauses()) + EnqueueChildren(Clause); +} void EnqueueVisitor::VisitAnnotateAttr(const AnnotateAttr *A) { EnqueueChildren(A); @@ -5270,7 +5314,7 @@ CXString clang_getCursorSpelling(CXCursor C) { if (const OverloadExpr *E = Storage.dyn_cast()) return cxstring::createDup(E->getName().getAsString()); OverloadedTemplateStorage *Ovl = - Storage.get(); + cast(Storage); if (Ovl->size() == 0) return cxstring::createEmpty(); return cxstring::createDup((*Ovl->begin())->getNameAsString()); @@ -6342,6 +6386,14 @@ CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) { return cxstring::createRef("OpenACCLoopConstruct"); case CXCursor_OpenACCCombinedConstruct: return cxstring::createRef("OpenACCCombinedConstruct"); + case CXCursor_OpenACCDataConstruct: + return cxstring::createRef("OpenACCDataConstruct"); + case CXCursor_OpenACCEnterDataConstruct: + return cxstring::createRef("OpenACCEnterDataConstruct"); + case CXCursor_OpenACCExitDataConstruct: + return cxstring::createRef("OpenACCExitDataConstruct"); + case CXCursor_OpenACCHostDataConstruct: + return cxstring::createRef("OpenACCHostDataConstruct"); } llvm_unreachable("Unhandled CXCursorKind"); @@ -7309,7 +7361,7 @@ unsigned clang_getNumOverloadedDecls(CXCursor C) { Storage.dyn_cast()) return S->size(); - const Decl *D = Storage.get(); + const Decl *D = cast(Storage); if (const UsingDecl *Using = dyn_cast(D)) return Using->shadow_size(); @@ -7332,7 +7384,7 @@ CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) { Storage.dyn_cast()) return MakeCXCursor(S->begin()[index], TU); - const Decl *D = Storage.get(); + const Decl *D = cast(Storage); if (const UsingDecl *Using = dyn_cast(D)) { // FIXME: This is, unfortunately, linear time. UsingDecl::shadow_iterator Pos = Using->shadow_begin(); diff --git a/clang/tools/libclang/CIndexCXX.cpp b/clang/tools/libclang/CIndexCXX.cpp index ea6f97d39644e..a1be70dde9f67 100644 --- a/clang/tools/libclang/CIndexCXX.cpp +++ b/clang/tools/libclang/CIndexCXX.cpp @@ -101,11 +101,11 @@ CXCursor clang_getSpecializedCursorTemplate(CXCursor C) { llvm::PointerUnion Result = ClassSpec->getSpecializedTemplateOrPartial(); - if (Result.is()) - Template = Result.get(); + if (isa(Result)) + Template = cast(Result); else - Template = Result.get(); - + Template = cast(Result); + } else Template = CXXRecord->getInstantiatedFromMemberClass(); } else if (const FunctionDecl *Function = dyn_cast(D)) { diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp index c8cf51d806132..26935c45ce5f8 100644 --- a/clang/tools/libclang/CXCursor.cpp +++ b/clang/tools/libclang/CXCursor.cpp @@ -888,6 +888,18 @@ CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent, case Stmt::OpenACCCombinedConstructClass: K = CXCursor_OpenACCCombinedConstruct; break; + case Stmt::OpenACCDataConstructClass: + K = CXCursor_OpenACCDataConstruct; + break; + case Stmt::OpenACCEnterDataConstructClass: + K = CXCursor_OpenACCEnterDataConstruct; + break; + case Stmt::OpenACCExitDataConstructClass: + K = CXCursor_OpenACCExitDataConstruct; + break; + case Stmt::OpenACCHostDataConstructClass: + K = CXCursor_OpenACCHostDataConstruct; + break; case Stmt::OMPTargetParallelGenericLoopDirectiveClass: K = CXCursor_OMPTargetParallelGenericLoopDirective; break; diff --git a/clang/unittests/AST/ASTContextParentMapTest.cpp b/clang/unittests/AST/ASTContextParentMapTest.cpp index 515dfb99e1126..9af0a46817a25 100644 --- a/clang/unittests/AST/ASTContextParentMapTest.cpp +++ b/clang/unittests/AST/ASTContextParentMapTest.cpp @@ -148,5 +148,54 @@ TEST(GetParents, FriendTypeLoc) { ElementsAre(DynTypedNode::create(FrA))); } +TEST(GetParents, UserDefinedTupleLikeTypes) { + MatchVerifier Verifier; + EXPECT_TRUE(Verifier.match( + R"( +namespace std { + +using size_t = __typeof(sizeof(int)); + +template +struct tuple_size; + +template +struct tuple_size : tuple_size{}; + +template +requires requires { tuple_size::value; } +struct tuple_size : tuple_size{}; + + +template +struct tuple_element; + + +} // namespace std + +struct Decomposable {}; + +template<> struct std::tuple_size { + static constexpr size_t value = 2; +}; + +template struct std::tuple_element { + using type = int; +}; + +template struct std::tuple_element { + using type = const int; +}; + +template +const int& get(const Decomposable& d); + +void F(const Decomposable& d) { + const auto& [x, y] = d; +} +)", + varDecl(hasName("x"), hasAncestor(decompositionDecl())), Lang_CXX20)); +} + } // end namespace ast_matchers } // end namespace clang diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp index abf07d094e62c..f3f314b723dfc 100644 --- a/clang/unittests/AST/ASTImporterTest.cpp +++ b/clang/unittests/AST/ASTImporterTest.cpp @@ -9657,7 +9657,7 @@ TEST_P(ASTImporterOptionSpecificTestBase, ImportConflictTypeAliasTemplate) { AST_MATCHER(ClassTemplateSpecializationDecl, hasInstantiatedFromMember) { if (auto Instantiate = Node.getInstantiatedFrom()) { if (auto *FromPartialSpecialization = - Instantiate.get()) { + cast(Instantiate)) { return nullptr != FromPartialSpecialization->getInstantiatedFromMember(); } } diff --git a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp index 39e7001393e5e..0f731f4532535 100644 --- a/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp +++ b/clang/unittests/Analysis/FlowSensitive/TransferTest.cpp @@ -25,6 +25,7 @@ #include "gtest/gtest.h" #include #include +#include #include namespace clang { @@ -143,6 +144,15 @@ const Formula &getFormula(const ValueDecl &D, const Environment &Env) { return cast(Env.getValue(D))->formula(); } +const BindingDecl *findBindingDecl(ASTContext &ASTCtx, std::string_view Name) { + using ast_matchers::bindingDecl; + using ast_matchers::hasName; + auto TargetNodes = + ast_matchers::match(bindingDecl(hasName(Name)).bind("v"), ASTCtx); + assert(TargetNodes.size() == 1 && "Name must be unique"); + return ast_matchers::selectFirst("v", TargetNodes); +} + TEST(TransferTest, CNotSupported) { TestInputs Inputs("void target() {}"); Inputs.Language = TestLanguage::Lang_C89; @@ -5515,10 +5525,10 @@ TEST(TransferTest, StructuredBindingAssignFromTupleLikeType) { ASSERT_THAT(Results.keys(), UnorderedElementsAre("p1", "p2")); const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1"); - const ValueDecl *BoundFooDecl = findValueDecl(ASTCtx, "BoundFoo"); + const ValueDecl *BoundFooDecl = findBindingDecl(ASTCtx, "BoundFoo"); ASSERT_THAT(BoundFooDecl, NotNull()); - const ValueDecl *BoundBarDecl = findValueDecl(ASTCtx, "BoundBar"); + const ValueDecl *BoundBarDecl = findBindingDecl(ASTCtx, "BoundBar"); ASSERT_THAT(BoundBarDecl, NotNull()); const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz"); @@ -5596,10 +5606,10 @@ TEST(TransferTest, StructuredBindingAssignRefFromTupleLikeType) { ASSERT_THAT(Results.keys(), UnorderedElementsAre("p1", "p2")); const Environment &Env1 = getEnvironmentAtAnnotation(Results, "p1"); - const ValueDecl *BoundFooDecl = findValueDecl(ASTCtx, "BoundFoo"); + const ValueDecl *BoundFooDecl = findBindingDecl(ASTCtx, "BoundFoo"); ASSERT_THAT(BoundFooDecl, NotNull()); - const ValueDecl *BoundBarDecl = findValueDecl(ASTCtx, "BoundBar"); + const ValueDecl *BoundBarDecl = findBindingDecl(ASTCtx, "BoundBar"); ASSERT_THAT(BoundBarDecl, NotNull()); const ValueDecl *BazDecl = findValueDecl(ASTCtx, "Baz"); diff --git a/clang/unittests/Basic/DiagnosticTest.cpp b/clang/unittests/Basic/DiagnosticTest.cpp index 36a77c7247655..e03d9a464df7f 100644 --- a/clang/unittests/Basic/DiagnosticTest.cpp +++ b/clang/unittests/Basic/DiagnosticTest.cpp @@ -12,6 +12,7 @@ #include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/IntrusiveRefCntPtr.h" @@ -20,6 +21,7 @@ #include "llvm/Support/VirtualFileSystem.h" #include "gmock/gmock.h" #include "gtest/gtest.h" +#include #include #include @@ -196,7 +198,17 @@ class SuppressionMappingTest : public testing::Test { return CaptureConsumer.StoredDiags; } + SourceLocation locForFile(llvm::StringRef FileName) { + auto Buf = MemoryBuffer::getMemBuffer("", FileName); + SourceManager &SM = Diags.getSourceManager(); + FileID FooID = SM.createFileID(std::move(Buf)); + return SM.getLocForStartOfFile(FooID); + } + private: + FileManager FM{{}, FS}; + SourceManager SM{Diags, FM}; + class CaptureDiagnosticConsumer : public DiagnosticConsumer { public: std::vector StoredDiags; @@ -255,9 +267,9 @@ TEST_F(SuppressionMappingTest, SuppressesGroup) { clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS); EXPECT_THAT(diags(), IsEmpty()); - EXPECT_TRUE( - Diags.isSuppressedViaMapping(diag::warn_unused_function, "foo.cpp")); - EXPECT_FALSE(Diags.isSuppressedViaMapping(diag::warn_deprecated, "foo.cpp")); + SourceLocation FooLoc = locForFile("foo.cpp"); + EXPECT_TRUE(Diags.isSuppressedViaMapping(diag::warn_unused_function, FooLoc)); + EXPECT_FALSE(Diags.isSuppressedViaMapping(diag::warn_deprecated, FooLoc)); } TEST_F(SuppressionMappingTest, EmitCategoryIsExcluded) { @@ -271,10 +283,10 @@ TEST_F(SuppressionMappingTest, EmitCategoryIsExcluded) { clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS); EXPECT_THAT(diags(), IsEmpty()); - EXPECT_TRUE( - Diags.isSuppressedViaMapping(diag::warn_unused_function, "bar.cpp")); - EXPECT_FALSE( - Diags.isSuppressedViaMapping(diag::warn_unused_function, "foo.cpp")); + EXPECT_TRUE(Diags.isSuppressedViaMapping(diag::warn_unused_function, + locForFile("bar.cpp"))); + EXPECT_FALSE(Diags.isSuppressedViaMapping(diag::warn_unused_function, + locForFile("foo.cpp"))); } TEST_F(SuppressionMappingTest, LongestMatchWins) { @@ -289,12 +301,12 @@ TEST_F(SuppressionMappingTest, LongestMatchWins) { clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS); EXPECT_THAT(diags(), IsEmpty()); + EXPECT_TRUE(Diags.isSuppressedViaMapping( + diag::warn_unused_function, locForFile("clang/lib/Basic/foo.h"))); + EXPECT_FALSE(Diags.isSuppressedViaMapping( + diag::warn_unused_function, locForFile("clang/lib/Sema/bar.h"))); EXPECT_TRUE(Diags.isSuppressedViaMapping(diag::warn_unused_function, - "clang/lib/Basic/foo.h")); - EXPECT_FALSE(Diags.isSuppressedViaMapping(diag::warn_unused_function, - "clang/lib/Sema/bar.h")); - EXPECT_TRUE(Diags.isSuppressedViaMapping(diag::warn_unused_function, - "clang/lib/Sema/foo.h")); + locForFile("clang/lib/Sema/foo.h"))); } TEST_F(SuppressionMappingTest, IsIgnored) { @@ -308,9 +320,7 @@ TEST_F(SuppressionMappingTest, IsIgnored) { clang::ProcessWarningOptions(Diags, Diags.getDiagnosticOptions(), *FS); ASSERT_THAT(diags(), IsEmpty()); - FileManager FM({}, FS); - SourceManager SM(Diags, FM); - + SourceManager &SM = Diags.getSourceManager(); auto ClangID = SM.createFileID(llvm::MemoryBuffer::getMemBuffer("", "clang/foo.h")); auto NonClangID = diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 250e51b542166..eeb857a914b1a 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -5724,6 +5724,24 @@ TEST_F(FormatTest, HashInMacroDefinition) { getLLVMStyleWithColumns(22)); verifyFormat("#define A void # ## #", getLLVMStyleWithColumns(22)); + +#if 0 + // FIXME: The correct format is: + verifyFormat("{\n" + " {\n" + "#define GEN_ID(_x) char *_x{#_x}\n" + " GEN_ID(one);\n" + " }\n" + "}"); +#endif + verifyFormat("{\n" + " {\n" + "#define GEN_ID(_x) \\\n" + " char *_x { #_x }\n" + " GEN_ID(one);\n" + " }\n" + "}", + getGoogleStyle()); } TEST_F(FormatTest, RespectWhitespaceInMacroDefinitions) { @@ -9441,6 +9459,15 @@ TEST_F(FormatTest, AlignsAfterOpenBracket) { " aaaaaaaaaaaaaaaa\n" ");", Style); + verifyFormat("void foo(\n" + " void (*foobarpntr)(\n" + " aaaaaaaaaaaaaaaaaa *,\n" + " bbbbbbbbbbbbbb *,\n" + " cccccccccccccccccccc *,\n" + " dddddddddddddddddd *\n" + " )\n" + ");", + Style); verifyFormat("aaaaaaa const aaaaaaaaaa{\n" " aaaaaaaaaaaaa(aaaaaaaaaaa, aaaaaaaaaaaaaaaa)\n" "};", @@ -27386,6 +27413,13 @@ TEST_F(FormatTest, RemoveSemicolon) { Style); #endif + verifyFormat("auto sgf = [] {\n" + " ogl = {\n" + " a, b, c, d, e,\n" + " };\n" + "};", + Style); + Style.TypenameMacros.push_back("STRUCT"); verifyFormat("STRUCT(T, B) { int i; };", Style); } diff --git a/clang/unittests/Format/FormatTestJS.cpp b/clang/unittests/Format/FormatTestJS.cpp index 4b15e7b7da339..663b00ca7af62 100644 --- a/clang/unittests/Format/FormatTestJS.cpp +++ b/clang/unittests/Format/FormatTestJS.cpp @@ -1753,6 +1753,10 @@ TEST_F(FormatTestJS, ClassDeclarations) { " x: {y: Z;} = {};\n" " private y: {y: Z;} = {};\n" "}"); + verifyFormat("class Foo {\n" + " private addGrammarCheckOneboxProductInfo(\n" + " productInfo: {[key: string]: string;}) {}\n" + "}"); // ':' is not a type declaration here. verifyFormat("class X {\n" diff --git a/clang/unittests/Format/TokenAnnotatorTest.cpp b/clang/unittests/Format/TokenAnnotatorTest.cpp index 9db3187ac44e7..38658fcb0e999 100644 --- a/clang/unittests/Format/TokenAnnotatorTest.cpp +++ b/clang/unittests/Format/TokenAnnotatorTest.cpp @@ -3346,6 +3346,25 @@ TEST_F(TokenAnnotatorTest, BraceKind) { EXPECT_BRACE_KIND(Tokens[11], BK_BracedInit); EXPECT_BRACE_KIND(Tokens[13], BK_Block); + Tokens = annotate("{\n" + " {\n" + "#define GEN_ID(_x) char *_x{#_x}\n" + " GEN_ID(one);\n" + " }\n" + "}"); + ASSERT_EQ(Tokens.size(), 23u) << Tokens; + EXPECT_TOKEN(Tokens[0], tok::l_brace, TT_BlockLBrace); + EXPECT_BRACE_KIND(Tokens[0], BK_Block); + EXPECT_TOKEN(Tokens[1], tok::l_brace, TT_BlockLBrace); + EXPECT_BRACE_KIND(Tokens[1], BK_Block); +#if 0 + // FIXME: + EXPECT_BRACE_KIND(Tokens[11], BK_BracedInit); + EXPECT_BRACE_KIND(Tokens[14], BK_BracedInit); +#endif + EXPECT_BRACE_KIND(Tokens[20], BK_Block); + EXPECT_BRACE_KIND(Tokens[21], BK_Block); + Tokens = annotate("a = class extends goog.a {};", getGoogleStyle(FormatStyle::LK_JavaScript)); ASSERT_EQ(Tokens.size(), 11u) << Tokens; diff --git a/clang/unittests/Frontend/CompilerInvocationTest.cpp b/clang/unittests/Frontend/CompilerInvocationTest.cpp index 4ff6824f1e21e..94ab9fe8451e0 100644 --- a/clang/unittests/Frontend/CompilerInvocationTest.cpp +++ b/clang/unittests/Frontend/CompilerInvocationTest.cpp @@ -31,17 +31,19 @@ class CommandLineTest : public ::testing::Test { public: IntrusiveRefCntPtr Diags; SmallVector GeneratedArgs; - SmallVector GeneratedArgsStorage; + BumpPtrAllocator Alloc; + StringSaver StringPool; CompilerInvocation Invocation; const char *operator()(const Twine &Arg) { - return GeneratedArgsStorage.emplace_back(Arg.str()).c_str(); + return StringPool.save(Arg).data(); } CommandLineTest() : Diags(CompilerInstance::createDiagnostics( *llvm::vfs::getRealFileSystem(), new DiagnosticOptions(), - new TextDiagnosticBuffer())) {} + new TextDiagnosticBuffer())), + StringPool(Alloc) {} }; template diff --git a/clang/unittests/Lex/LexerTest.cpp b/clang/unittests/Lex/LexerTest.cpp index 47aa2c131a304..aead7fb899d0a 100644 --- a/clang/unittests/Lex/LexerTest.cpp +++ b/clang/unittests/Lex/LexerTest.cpp @@ -652,6 +652,38 @@ TEST_F(LexerTest, RawAndNormalLexSameForLineComments) { EXPECT_TRUE(ToksView.empty()); } +TEST_F(LexerTest, GetRawTokenOnEscapedNewLineChecksWhitespace) { + const llvm::StringLiteral Source = R"cc( + #define ONE \ + 1 + + int i = ONE; + )cc"; + std::vector Toks = + CheckLex(Source, {tok::kw_int, tok::identifier, tok::equal, + tok::numeric_constant, tok::semi}); + + // Set up by getting the raw token for the `1` in the macro definition. + const Token &OneExpanded = Toks[3]; + Token Tok; + ASSERT_FALSE( + Lexer::getRawToken(OneExpanded.getLocation(), Tok, SourceMgr, LangOpts)); + // The `ONE`. + ASSERT_EQ(Tok.getKind(), tok::raw_identifier); + ASSERT_FALSE( + Lexer::getRawToken(SourceMgr.getSpellingLoc(OneExpanded.getLocation()), + Tok, SourceMgr, LangOpts)); + // The `1` in the macro definition. + ASSERT_EQ(Tok.getKind(), tok::numeric_constant); + + // Go back 4 characters: two spaces, one newline, and the backslash. + SourceLocation EscapedNewLineLoc = Tok.getLocation().getLocWithOffset(-4); + // Expect true (=failure) because the whitespace immediately after the + // escaped newline is not ignored. + EXPECT_TRUE(Lexer::getRawToken(EscapedNewLineLoc, Tok, SourceMgr, LangOpts, + /*IgnoreWhiteSpace=*/false)); +} + TEST(LexerPreambleTest, PreambleBounds) { std::vector Cases = { R"cc([[ diff --git a/clang/unittests/Serialization/CMakeLists.txt b/clang/unittests/Serialization/CMakeLists.txt index e7eebd0cb9823..e7005b5d511eb 100644 --- a/clang/unittests/Serialization/CMakeLists.txt +++ b/clang/unittests/Serialization/CMakeLists.txt @@ -11,6 +11,7 @@ add_clang_unittest(SerializationTests ModuleCacheTest.cpp NoCommentsTest.cpp PreambleInNamedModulesTest.cpp + LoadSpecLazilyTest.cpp SourceLocationEncodingTest.cpp VarDeclConstantInitTest.cpp ) diff --git a/clang/unittests/Serialization/LoadSpecLazilyTest.cpp b/clang/unittests/Serialization/LoadSpecLazilyTest.cpp new file mode 100644 index 0000000000000..7cc074c51fcd0 --- /dev/null +++ b/clang/unittests/Serialization/LoadSpecLazilyTest.cpp @@ -0,0 +1,264 @@ +//== unittests/Serialization/LoadSpecLazily.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 "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/FrontendAction.h" +#include "clang/Frontend/FrontendActions.h" +#include "clang/Parse/ParseAST.h" +#include "clang/Serialization/ASTDeserializationListener.h" +#include "clang/Tooling/Tooling.h" +#include "gtest/gtest.h" + +using namespace llvm; +using namespace clang; +using namespace clang::tooling; + +namespace { + +class LoadSpecLazilyTest : public ::testing::Test { + void SetUp() override { + ASSERT_FALSE( + sys::fs::createUniqueDirectory("load-spec-lazily-test", TestDir)); + } + + void TearDown() override { sys::fs::remove_directories(TestDir); } + +public: + SmallString<256> TestDir; + + void addFile(StringRef Path, StringRef Contents) { + ASSERT_FALSE(sys::path::is_absolute(Path)); + + SmallString<256> AbsPath(TestDir); + sys::path::append(AbsPath, Path); + + ASSERT_FALSE( + sys::fs::create_directories(llvm::sys::path::parent_path(AbsPath))); + + std::error_code EC; + llvm::raw_fd_ostream OS(AbsPath, EC); + ASSERT_FALSE(EC); + OS << Contents; + } + + std::string GenerateModuleInterface(StringRef ModuleName, + StringRef Contents) { + std::string FileName = llvm::Twine(ModuleName + ".cppm").str(); + addFile(FileName, Contents); + + IntrusiveRefCntPtr VFS = + llvm::vfs::createPhysicalFileSystem(); + IntrusiveRefCntPtr Diags = + CompilerInstance::createDiagnostics(*VFS, new DiagnosticOptions()); + CreateInvocationOptions CIOpts; + CIOpts.Diags = Diags; + CIOpts.VFS = VFS; + + std::string CacheBMIPath = + llvm::Twine(TestDir + "/" + ModuleName + ".pcm").str(); + std::string PrebuiltModulePath = + "-fprebuilt-module-path=" + TestDir.str().str(); + const char *Args[] = {"clang++", + "-std=c++20", + "--precompile", + PrebuiltModulePath.c_str(), + "-working-directory", + TestDir.c_str(), + "-I", + TestDir.c_str(), + FileName.c_str(), + "-o", + CacheBMIPath.c_str()}; + std::shared_ptr Invocation = + createInvocation(Args, CIOpts); + EXPECT_TRUE(Invocation); + + CompilerInstance Instance; + Instance.setDiagnostics(Diags.get()); + Instance.setInvocation(Invocation); + Instance.getFrontendOpts().OutputFile = CacheBMIPath; + // Avoid memory leaks. + Instance.getFrontendOpts().DisableFree = false; + GenerateModuleInterfaceAction Action; + EXPECT_TRUE(Instance.ExecuteAction(Action)); + EXPECT_FALSE(Diags->hasErrorOccurred()); + + return CacheBMIPath; + } +}; + +enum class CheckingMode { Forbidden, Required }; + +class DeclsReaderListener : public ASTDeserializationListener { + StringRef SpeficiedName; + CheckingMode Mode; + + bool ReadedSpecifiedName = false; + +public: + void DeclRead(GlobalDeclID ID, const Decl *D) override { + auto *ND = dyn_cast(D); + if (!ND) + return; + + ReadedSpecifiedName |= ND->getName().contains(SpeficiedName); + if (Mode == CheckingMode::Forbidden) { + EXPECT_FALSE(ReadedSpecifiedName); + } + } + + DeclsReaderListener(StringRef SpeficiedName, CheckingMode Mode) + : SpeficiedName(SpeficiedName), Mode(Mode) {} + + ~DeclsReaderListener() { + if (Mode == CheckingMode::Required) { + EXPECT_TRUE(ReadedSpecifiedName); + } + } +}; + +class LoadSpecLazilyConsumer : public ASTConsumer { + DeclsReaderListener Listener; + +public: + LoadSpecLazilyConsumer(StringRef SpecifiedName, CheckingMode Mode) + : Listener(SpecifiedName, Mode) {} + + ASTDeserializationListener *GetASTDeserializationListener() override { + return &Listener; + } +}; + +class CheckLoadSpecLazilyAction : public ASTFrontendAction { + StringRef SpecifiedName; + CheckingMode Mode; + +public: + std::unique_ptr + CreateASTConsumer(CompilerInstance &CI, StringRef /*Unused*/) override { + return std::make_unique(SpecifiedName, Mode); + } + + CheckLoadSpecLazilyAction(StringRef SpecifiedName, CheckingMode Mode) + : SpecifiedName(SpecifiedName), Mode(Mode) {} +}; + +TEST_F(LoadSpecLazilyTest, BasicTest) { + GenerateModuleInterface("M", R"cpp( +export module M; +export template +class A {}; +export class ShouldNotBeLoaded {}; +export class Temp { + A AS; +}; + )cpp"); + + const char *test_file_contents = R"cpp( +import M; +A a; + )cpp"; + std::string DepArg = "-fprebuilt-module-path=" + TestDir.str().str(); + EXPECT_TRUE( + runToolOnCodeWithArgs(std::make_unique( + "ShouldNotBeLoaded", CheckingMode::Forbidden), + test_file_contents, + { + "-std=c++20", + DepArg.c_str(), + "-I", + TestDir.c_str(), + }, + "test.cpp")); +} + +TEST_F(LoadSpecLazilyTest, ChainedTest) { + GenerateModuleInterface("M", R"cpp( +export module M; +export template +class A {}; + )cpp"); + + GenerateModuleInterface("N", R"cpp( +export module N; +export import M; +export class ShouldNotBeLoaded {}; +export class Temp { + A AS; +}; + )cpp"); + + const char *test_file_contents = R"cpp( +import N; +A a; + )cpp"; + std::string DepArg = "-fprebuilt-module-path=" + TestDir.str().str(); + EXPECT_TRUE( + runToolOnCodeWithArgs(std::make_unique( + "ShouldNotBeLoaded", CheckingMode::Forbidden), + test_file_contents, + { + "-std=c++20", + DepArg.c_str(), + "-I", + TestDir.c_str(), + }, + "test.cpp")); +} + +/// Test that we won't crash due to we may invalidate the lazy specialization +/// lookup table during the loading process. +TEST_F(LoadSpecLazilyTest, ChainedTest2) { + GenerateModuleInterface("M", R"cpp( +export module M; +export template +class A {}; + +export class B {}; + +export class C { + A D; +}; + )cpp"); + + GenerateModuleInterface("N", R"cpp( +export module N; +export import M; +export class MayBeLoaded {}; + +export class Temp { + A AS; +}; + +export class ExportedClass {}; + +export template<> class A { + A AS; + A AB; +}; + )cpp"); + + const char *test_file_contents = R"cpp( +import N; +Temp T; +A a; + )cpp"; + std::string DepArg = "-fprebuilt-module-path=" + TestDir.str().str(); + EXPECT_TRUE(runToolOnCodeWithArgs(std::make_unique( + "MayBeLoaded", CheckingMode::Required), + test_file_contents, + { + "-std=c++20", + DepArg.c_str(), + "-I", + TestDir.c_str(), + }, + "test.cpp")); +} + +} // namespace diff --git a/clang/unittests/StaticAnalyzer/Z3CrosscheckOracleTest.cpp b/clang/unittests/StaticAnalyzer/Z3CrosscheckOracleTest.cpp index ef07e47ee911b..626f5c163d17d 100644 --- a/clang/unittests/StaticAnalyzer/Z3CrosscheckOracleTest.cpp +++ b/clang/unittests/StaticAnalyzer/Z3CrosscheckOracleTest.cpp @@ -38,8 +38,8 @@ static const AnalyzerOptions DefaultOpts = [] { // Remember to update the tests in this file when these values change. // Also update the doc comment of `interpretQueryResult`. - assert(Config.Z3CrosscheckRLimitThreshold == 400'000); - assert(Config.Z3CrosscheckTimeoutThreshold == 300_ms); + assert(Config.Z3CrosscheckRLimitThreshold == 0); + assert(Config.Z3CrosscheckTimeoutThreshold == 15'000_ms); // Usually, when the timeout/rlimit threshold is reached, Z3 only slightly // overshoots until it realizes that it overshoot and needs to back off. // Consequently, the measured timeout should be fairly close to the threshold. @@ -47,8 +47,17 @@ static const AnalyzerOptions DefaultOpts = [] { return Config; }(); +static const AnalyzerOptions LimitedOpts = [] { + AnalyzerOptions Config = DefaultOpts; + Config.Z3CrosscheckEQClassTimeoutThreshold = 700_ms; + Config.Z3CrosscheckTimeoutThreshold = 300_step; + Config.Z3CrosscheckRLimitThreshold = 400'000_step; + return Config; +}(); + namespace { +template class Z3CrosscheckOracleTest : public testing::Test { public: Z3Decision interpretQueryResult(const Z3Result &Result) { @@ -56,58 +65,100 @@ class Z3CrosscheckOracleTest : public testing::Test { } private: - Z3CrosscheckOracle Oracle = Z3CrosscheckOracle(DefaultOpts); + Z3CrosscheckOracle Oracle = Z3CrosscheckOracle(Opts); }; -TEST_F(Z3CrosscheckOracleTest, AcceptsFirstSAT) { +using DefaultZ3CrosscheckOracleTest = Z3CrosscheckOracleTest; +using LimitedZ3CrosscheckOracleTest = Z3CrosscheckOracleTest; + +TEST_F(DefaultZ3CrosscheckOracleTest, AcceptsFirstSAT) { + ASSERT_EQ(AcceptReport, interpretQueryResult({SAT, 25_ms, 1000_step})); +} +TEST_F(LimitedZ3CrosscheckOracleTest, AcceptsFirstSAT) { ASSERT_EQ(AcceptReport, interpretQueryResult({SAT, 25_ms, 1000_step})); } -TEST_F(Z3CrosscheckOracleTest, AcceptsSAT) { +TEST_F(DefaultZ3CrosscheckOracleTest, AcceptsSAT) { + ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); + ASSERT_EQ(AcceptReport, interpretQueryResult({SAT, 25_ms, 1000_step})); +} +TEST_F(LimitedZ3CrosscheckOracleTest, AcceptsSAT) { ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); ASSERT_EQ(AcceptReport, interpretQueryResult({SAT, 25_ms, 1000_step})); } -TEST_F(Z3CrosscheckOracleTest, SATWhenItGoesOverTime) { +TEST_F(DefaultZ3CrosscheckOracleTest, SATWhenItGoesOverTime) { + // Even if it times out, if it is SAT, we should accept it. + ASSERT_EQ(AcceptReport, interpretQueryResult({SAT, 15'010_ms, 1000_step})); +} +TEST_F(LimitedZ3CrosscheckOracleTest, SATWhenItGoesOverTime) { // Even if it times out, if it is SAT, we should accept it. ASSERT_EQ(AcceptReport, interpretQueryResult({SAT, 310_ms, 1000_step})); } -TEST_F(Z3CrosscheckOracleTest, UNSATWhenItGoesOverTime) { +TEST_F(DefaultZ3CrosscheckOracleTest, UNSATWhenItGoesOverTime) { + ASSERT_EQ(RejectEQClass, interpretQueryResult({UNSAT, 15'010_ms, 1000_step})); +} +TEST_F(LimitedZ3CrosscheckOracleTest, UNSATWhenItGoesOverTime) { ASSERT_EQ(RejectEQClass, interpretQueryResult({UNSAT, 310_ms, 1000_step})); } -TEST_F(Z3CrosscheckOracleTest, RejectsTimeout) { +TEST_F(DefaultZ3CrosscheckOracleTest, RejectsTimeout) { + ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); + ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); + ASSERT_EQ(RejectEQClass, interpretQueryResult({UNDEF, 15'010_ms, 1000_step})); +} +TEST_F(LimitedZ3CrosscheckOracleTest, RejectsTimeout) { ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); ASSERT_EQ(RejectEQClass, interpretQueryResult({UNDEF, 310_ms, 1000_step})); } -TEST_F(Z3CrosscheckOracleTest, RejectsUNSATs) { +TEST_F(DefaultZ3CrosscheckOracleTest, RejectsUNSATs) { + ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); + ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); + ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); + ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); +} +TEST_F(LimitedZ3CrosscheckOracleTest, RejectsUNSATs) { ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); } -// Testing cut heuristics: -// ======================= +// Testing cut heuristics of the two configurations: +// ================================================= -TEST_F(Z3CrosscheckOracleTest, RejectEQClassIfSpendsTooMuchTotalTime) { +TEST_F(DefaultZ3CrosscheckOracleTest, RejectEQClassIfSpendsTooMuchTotalTime) { + // Simulate long queries, that barely doesn't trigger the timeout. + ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 14'990_ms, 1000_step})); + ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 14'990_ms, 1000_step})); + ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 14'990_ms, 1000_step})); +} +TEST_F(LimitedZ3CrosscheckOracleTest, RejectEQClassIfSpendsTooMuchTotalTime) { // Simulate long queries, that barely doesn't trigger the timeout. ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 290_ms, 1000_step})); ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 290_ms, 1000_step})); ASSERT_EQ(RejectEQClass, interpretQueryResult({UNSAT, 290_ms, 1000_step})); } -TEST_F(Z3CrosscheckOracleTest, SATWhenItSpendsTooMuchTotalTime) { +TEST_F(DefaultZ3CrosscheckOracleTest, SATWhenItSpendsTooMuchTotalTime) { + // Simulate long queries, that barely doesn't trigger the timeout. + ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 14'990_ms, 1000_step})); + ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 14'990_ms, 1000_step})); + ASSERT_EQ(AcceptReport, interpretQueryResult({SAT, 14'990_ms, 1000_step})); +} +TEST_F(LimitedZ3CrosscheckOracleTest, SATWhenItSpendsTooMuchTotalTime) { // Simulate long queries, that barely doesn't trigger the timeout. ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 290_ms, 1000_step})); ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 290_ms, 1000_step})); ASSERT_EQ(AcceptReport, interpretQueryResult({SAT, 290_ms, 1000_step})); } -TEST_F(Z3CrosscheckOracleTest, RejectEQClassIfAttemptsManySmallQueries) { +// Z3CrosscheckEQClassTimeoutThreshold is disabled in default configuration, so +// it doesn't make sense to test that. +TEST_F(LimitedZ3CrosscheckOracleTest, RejectEQClassIfAttemptsManySmallQueries) { // Simulate quick, but many queries: 35 quick UNSAT queries. // 35*20ms = 700ms, which is equal to the 700ms threshold. for (int i = 0; i < 35; ++i) { @@ -117,7 +168,9 @@ TEST_F(Z3CrosscheckOracleTest, RejectEQClassIfAttemptsManySmallQueries) { ASSERT_EQ(RejectEQClass, interpretQueryResult({UNSAT, 1_ms, 1000_step})); } -TEST_F(Z3CrosscheckOracleTest, SATWhenIfAttemptsManySmallQueries) { +// Z3CrosscheckEQClassTimeoutThreshold is disabled in default configuration, so +// it doesn't make sense to test that. +TEST_F(LimitedZ3CrosscheckOracleTest, SATWhenItAttemptsManySmallQueries) { // Simulate quick, but many queries: 35 quick UNSAT queries. // 35*20ms = 700ms, which is equal to the 700ms threshold. for (int i = 0; i < 35; ++i) { @@ -128,16 +181,34 @@ TEST_F(Z3CrosscheckOracleTest, SATWhenIfAttemptsManySmallQueries) { ASSERT_EQ(AcceptReport, interpretQueryResult({SAT, 200_ms, 1000_step})); } -TEST_F(Z3CrosscheckOracleTest, RejectEQClassIfExhaustsRLimit) { +// Z3CrosscheckRLimitThreshold is disabled in default configuration, so it +// doesn't make sense to test that. +TEST_F(LimitedZ3CrosscheckOracleTest, RejectEQClassIfExhaustsRLimit) { ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); ASSERT_EQ(RejectEQClass, interpretQueryResult({UNDEF, 25_ms, 405'000_step})); } -TEST_F(Z3CrosscheckOracleTest, SATWhenItExhaustsRLimit) { +// Z3CrosscheckRLimitThreshold is disabled in default configuration, so it +// doesn't make sense to test that. +TEST_F(LimitedZ3CrosscheckOracleTest, SATWhenItExhaustsRLimit) { ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); ASSERT_EQ(RejectReport, interpretQueryResult({UNSAT, 25_ms, 1000_step})); ASSERT_EQ(AcceptReport, interpretQueryResult({SAT, 25_ms, 405'000_step})); } +// Demonstrate the weaknesses of the default configuration: +// ======================================================== + +TEST_F(DefaultZ3CrosscheckOracleTest, ManySlowQueriesHangTheAnalyzer) { + // Simulate many slow queries: 250 slow UNSAT queries. + // 250*14000ms = 3500s, ~1 hour. Since we disabled the total time limitation, + // this eqclass would take roughly 1 hour to process. + // It doesn't matter what rlimit the queries consume. + for (int i = 0; i < 250; ++i) { + ASSERT_EQ(RejectReport, + interpretQueryResult({UNSAT, 14'000_ms, 1'000'000_step})); + } +} + } // namespace diff --git a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp index 4ff5e8b65a686..a551f83ff3f9c 100644 --- a/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp +++ b/clang/unittests/Tooling/Syntax/BuildTreeTest.cpp @@ -5659,8 +5659,6 @@ struct X { }; [[void (X::*xp)();]] [[void (X::**xpp)(const int*);]] -// FIXME: Generate the right syntax tree for this type, -// i.e. create a syntax node for the outer member pointer [[void (X::Y::*xyp)(const int*, char);]] )cpp", {R"txt( @@ -5714,9 +5712,9 @@ SimpleDeclaration | `-SimpleDeclarator ListElement | |-ParenDeclarator | | |-'(' OpenParen -| | |-'X' -| | |-'::' | | |-MemberPointer +| | | |-'X' +| | | |-'::' | | | |-'Y' | | | |-'::' | | | `-'*' diff --git a/clang/utils/TableGen/ClangAttrEmitter.cpp b/clang/utils/TableGen/ClangAttrEmitter.cpp index 630beaef983bc..cc6a8eaebd44e 100644 --- a/clang/utils/TableGen/ClangAttrEmitter.cpp +++ b/clang/utils/TableGen/ClangAttrEmitter.cpp @@ -3183,7 +3183,6 @@ void clang::EmitClangAttrClass(const RecordKeeper &Records, raw_ostream &OS) { OS << "#ifndef LLVM_CLANG_ATTR_CLASSES_INC\n"; OS << "#define LLVM_CLANG_ATTR_CLASSES_INC\n"; - OS << "#include \"clang/Support/Compiler.h\"\n\n"; emitAttributes(Records, OS, true); diff --git a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp index 6a4a64a081306..72b3468dac486 100644 --- a/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp +++ b/clang/utils/TableGen/ClangDiagnosticsEmitter.cpp @@ -362,7 +362,7 @@ void InferPedantic::compute(VecOrSet DiagsInPedantic, if (auto *V = DiagsInPedantic.dyn_cast()) V->push_back(R); else - DiagsInPedantic.get()->insert(R); + cast(DiagsInPedantic)->insert(R); } if (!GroupsInPedantic) @@ -389,7 +389,7 @@ void InferPedantic::compute(VecOrSet DiagsInPedantic, if (auto *V = GroupsInPedantic.dyn_cast()) V->push_back(Group); else - GroupsInPedantic.get()->insert(Group); + cast(GroupsInPedantic)->insert(Group); } } @@ -1907,8 +1907,7 @@ void clang::EmitClangDiagDocs(const RecordKeeper &Records, raw_ostream &OS) { // Write out the diagnostic groups. for (const Record *G : DiagGroups) { bool IsRemarkGroup = isRemarkGroup(G, DiagsInGroup); - auto &GroupInfo = - DiagsInGroup[std::string(G->getValueAsString("GroupName"))]; + auto &GroupInfo = DiagsInGroup[G->getValueAsString("GroupName")]; bool IsSynonym = GroupInfo.DiagsInGroup.empty() && GroupInfo.SubGroups.size() == 1; diff --git a/clang/utils/TableGen/SveEmitter.cpp b/clang/utils/TableGen/SveEmitter.cpp index 2d9f5c3381018..14e5637f62517 100644 --- a/clang/utils/TableGen/SveEmitter.cpp +++ b/clang/utils/TableGen/SveEmitter.cpp @@ -253,7 +253,7 @@ class Intrinsic { /// Return true if the intrinsic takes a splat operand. bool hasSplat() const { // These prototype modifiers are described in arm_sve.td. - return Proto.find_first_of("ajfrKLR@") != std::string::npos; + return Proto.find_first_of("ajfrKLR@!") != std::string::npos; } /// Return the parameter index of the splat operand. @@ -262,7 +262,7 @@ class Intrinsic { for (; I < Proto.size(); ++I, ++Param) { if (Proto[I] == 'a' || Proto[I] == 'j' || Proto[I] == 'f' || Proto[I] == 'r' || Proto[I] == 'K' || Proto[I] == 'L' || - Proto[I] == 'R' || Proto[I] == '@') + Proto[I] == 'R' || Proto[I] == '@' || Proto[I] == '!') break; // Multivector modifier can be skipped @@ -910,6 +910,11 @@ void SVEType::applyModifier(char Mod) { Kind = MFloat8; ElementBitwidth = 8; break; + case '!': + Kind = MFloat8; + Bitwidth = ElementBitwidth = 8; + NumVectors = 0; + break; case '.': llvm_unreachable(". is never a type in itself"); break; diff --git a/clang/utils/perf-training/bolt.lit.cfg b/clang/utils/perf-training/bolt.lit.cfg index 1d0cf9a8a17a8..dbb2dd3fd8587 100644 --- a/clang/utils/perf-training/bolt.lit.cfg +++ b/clang/utils/perf-training/bolt.lit.cfg @@ -4,6 +4,7 @@ from lit import Test import lit.formats import lit.util import os +import re import subprocess clang_bolt_mode = config.clang_bolt_mode.lower() @@ -20,9 +21,13 @@ elif clang_bolt_mode == "perf": else: assert 0, "Unsupported CLANG_BOLT_MODE variable" -config.clang = perf_wrapper + os.path.realpath( +clang_nowrapper = os.path.realpath( lit.util.which(clang_binary, config.clang_tools_dir) ).replace("\\", "/") +config.clang = perf_wrapper + clang_nowrapper +config.cmake_compiler_args = "-DCMAKE_C_COMPILER='{0}' -DCMAKE_CXX_COMPILER='{0};--driver-mode=g++'".format( + re.sub(r"\s+", ";", clang_nowrapper) +) config.name = "Clang Perf Training" config.suffixes = [ @@ -49,6 +54,8 @@ config.substitutions.append(("%clang_cpp", f" {config.clang} --driver-mode=g++ " config.substitutions.append(("%clang_skip_driver", config.clang)) config.substitutions.append(("%clang", config.clang)) config.substitutions.append(("%test_root", config.test_exec_root)) +config.substitutions.append(("%cmake_compiler_args", config.cmake_compiler_args)) config.substitutions.append(('%cmake_generator', config.cmake_generator)) config.substitutions.append(('%cmake', config.cmake_exe)) config.substitutions.append(('%llvm_src_dir', config.llvm_src_dir)) +config.substitutions.append(('%perf_wrapper', perf_wrapper)) diff --git a/clang/utils/perf-training/lit.cfg b/clang/utils/perf-training/lit.cfg index 654961e215da6..adefc7893ac44 100644 --- a/clang/utils/perf-training/lit.cfg +++ b/clang/utils/perf-training/lit.cfg @@ -31,14 +31,19 @@ cc1_wrapper = '%s %s/perf-helper.py cc1' % (config.python_exe, config.perf_helpe use_lit_shell = os.environ.get("LIT_USE_INTERNAL_SHELL") config.test_format = lit.formats.ShTest(use_lit_shell == "0") +config.cmake_compiler_args = '-DCMAKE_C_COMPILER="{0}" -DCMAKE_CXX_COMPILER="{0};--driver-mode=g++"'.format( + config.clang.replace(' ', ';') +) config.substitutions.append( ('%clang_cpp_skip_driver', ' %s %s %s ' % (cc1_wrapper, config.clang, sysroot_flags))) config.substitutions.append( ('%clang_cpp', ' %s --driver-mode=g++ %s ' % (config.clang, sysroot_flags))) config.substitutions.append( ('%clang_skip_driver', ' %s %s %s ' % (cc1_wrapper, config.clang, sysroot_flags))) config.substitutions.append( ('%clang', '%s %s ' % (config.clang, sysroot_flags) ) ) config.substitutions.append( ('%test_root', config.test_exec_root ) ) +config.substitutions.append( ('%cmake_compiler_args', config.cmake_compiler_args)) config.substitutions.append( ('%cmake_generator', config.cmake_generator ) ) config.substitutions.append( ('%cmake', config.cmake_exe ) ) config.substitutions.append( ('%llvm_src_dir', config.llvm_src_dir ) ) +config.substitutions.append( ('%perf_wrapper', '' ) ) config.environment['LLVM_PROFILE_FILE'] = 'perf-training-%4m.profraw' diff --git a/clang/utils/perf-training/llvm-support/build.test b/clang/utils/perf-training/llvm-support/build.test index f29a594c84686..32ce9a870b91d 100644 --- a/clang/utils/perf-training/llvm-support/build.test +++ b/clang/utils/perf-training/llvm-support/build.test @@ -1,2 +1,2 @@ -RUN: %cmake -G %cmake_generator -B %t -S %llvm_src_dir -DCMAKE_C_COMPILER=%clang -DCMAKE_CXX_COMPILER=%clang -DCMAKE_CXX_FLAGS="--driver-mode=g++" -DCMAKE_BUILD_TYPE=Release -RUN: %cmake --build %t -v --target LLVMSupport +RUN: %cmake -G %cmake_generator -B %t -S %llvm_src_dir %cmake_compiler_args -DCMAKE_BUILD_TYPE=Release +RUN: %perf_wrapper %cmake --build %t -v --target LLVMSupport diff --git a/clang/utils/perf-training/perf-helper.py b/clang/utils/perf-training/perf-helper.py index 3ed42a187fd80..d76c6ede3fe5a 100644 --- a/clang/utils/perf-training/perf-helper.py +++ b/clang/utils/perf-training/perf-helper.py @@ -36,7 +36,7 @@ def clean(args): + "\tRemoves all files with extension from ." ) return 1 - for path in args[1:-1]: + for path in args[0:-1]: for filename in findFilesWithExtension(path, args[-1]): os.remove(filename) return 0 diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index fdb9807b1168c..a8e79cd3475ab 100755 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -239,7 +239,7 @@

C++2c implementation status

Remove Deprecated Array Comparisons from C++26
P2865R6 - No + Clang 20 Structured Bindings can introduce a Pack diff --git a/compiler-rt/Maintainers.md b/compiler-rt/Maintainers.md new file mode 100644 index 0000000000000..5faf6741c4679 --- /dev/null +++ b/compiler-rt/Maintainers.md @@ -0,0 +1,110 @@ +# Compiler-rt maintainers + +This file is a list of the +[maintainers](https://llvm.org/docs/DeveloperPolicy.html#maintainers) for +LLVM compiler-rt. + +## Current Maintainers + +The following people are the active maintainers for the project. Please reach +out to them for code reviews, questions about their area of expertise, or other +assistance. + +### Builtins Library + +Saleem Abdulrasool \ +compnerd@compnerd.org (email), [compnerd](https://github.com/compnerd) (GitHub) + +### CFI + +Peter Collingbourne \ +peter@pcc.me.uk (email), [pcc](https://github.com/pcc) (GitHub) + +### CMake build + +Petr Hosek \ +phosek@google.com (email), [petrhosek](https://github.com/petrhosek) (GitHub) + +### CRT + +Petr Hosek \ +phosek@google.com (email), [petrhosek](https://github.com/petrhosek) (GitHub) + +### GWP ASAN + +Christopher Ferris \ +cferris@google.com (email), [cferris1000](https://github.com/cferris1000) (GitHub) + +### MemProfiling + +Teresa Johnson \ +tejohnson@google.com (email), [teresajohnson](https://github.com/teresajohnson) (GitHub) + +### SafeStack + +Peter Collingbourne \ +peter@pcc.me.uk (email), [pcc](https://github.com/pcc) (GitHub) + +### Sanitizers + +#### Sanitizers not covered by someone else + +Vitaly Buka \ +vitalybuka@google.com (email), [vitalybuka](https://github.com/vitalybuka) (GitHub) \ +Alexander Potapenko \ +glider@google.com (email), [ramosian-glider](https://github.com/ramosian-glider) (GitHub) + +#### Data Flow Sanitizer + +Andrew Browne \ +browneee@google.com (email), [browneee](https://github.com/browneee) (GitHub) + +#### Numerical Sanitizer (NSAN) + +Alexander Shaposhnikov \ +alexander.v.shaposhnikov@gmail.com (email), [alexander-shaposhnikov](https://github.com/alexander-shaposhnikov) (GitHub) + +#### Realtime Sanitizer (RTSan) + +Christopher Apple \ +cja-private@pm.me (email), [cjappl](https://github.com/cjappl) (GitHub) \ +David Trevelyan \ +david.trevelyan@gmail.com (email), [davidtrevelyan](https://github.com/davidtrevelyan) (GitHub) + +#### Thread Sanitizer + +Dmitry Vyukov \ +dvyukov@google.com (email), [dvyukov](https://github.com/dvyukov) (GitHub) + +#### Undefined Behavior Sanitizer + +Richard Smith \ +richard-llvm@metafoo.co.uk (email), [zygoloid](https://github.com/zygoloid) (GitHub) + +### ORC + +Lang Hames \ +lhames@gmail.com (email), [lhames](https://github.com/lhames) (GitHub) + +### Profile runtime library + +Bill Wendling \ +isanbard@gmail.com (email), [isanbard](https://github.com/isanbard) (GitHub) + +### SCUDO + +Christopher Ferris \ +cferris@google.com (email), [cferris1000](https://github.com/cferris1000) (GitHub) + +## Inactive Maintainers + +The following people have graciously spent time performing maintainer +responsibilities but are no longer active in that role. Thank you for all your +help with the success of the project! + +### Inactive or former component maintainers + +Kostya Serebryany ([kcc](https://github.com/kcc)) -- Sanitizers \ +Evgeniy Stepanov ([eugenis](https://github.com/eugenis)) -- Sanitizers \ +Kostya Kortchinsky ([cryptoad](https://github.com/cryptoad)) -- SCUDO \ +Mitch Phillips ([hctim](https://github.com/hctim)) -- GWP ASAN diff --git a/compiler-rt/Maintainers.txt b/compiler-rt/Maintainers.txt deleted file mode 100644 index bd51a1073cc38..0000000000000 --- a/compiler-rt/Maintainers.txt +++ /dev/null @@ -1,77 +0,0 @@ -This file is a list of the people responsible for ensuring that patches for a -particular part of compiler-rt are reviewed, either by themself or by -someone else. They are also the gatekeepers for their part of compiler-rt, with -the final word on what goes in or not. - -The list is sorted by surname and formatted to allow easy grepping and -beautification by scripts. The fields are: name (N), email (E), web-address -(W), PGP key ID and fingerprint (P), description (D), and snail-mail address -(S). - -N: Saleem Abdulrasool -E: compnerd@compnerd.org -D: builtins library - -N: Andrew Browne -E: browneee@google.com -D: DataFlowSanitizer - -N: Vitaly Buka -E: vitalybuka@google.com -D: Sanitizers - -N: Peter Collingbourne -E: peter@pcc.me.uk -D: CFI, SafeStack - -N: Lang Hames -E: lhames@gmail.com -D: ORC - -N: Petr Hosek -E: phosek@google.com -D: CRT, CMake build - -N: Teresa Johnson -E: tejohnson@google.com -D: MemProf - -N: Kostya Kortchinsky -E: kostya.kortchinsky@gmail.com -D: SCUDO - -N: Mitch Phillips -E: mitchp@google.com -D: GWP ASAN - -N: Alexander Potapenko -E: glider@google.com -D: Sanitizers - -N: Kostya Serebryany -E: kcc@google.com -D: AddressSanitizer, sanitizer_common, LeakSanitizer, LibFuzzer - -N: Richard Smith -E: richard-llvm@metafoo.co.uk -D: UndefinedBehaviorSanitizer - -N: Evgeniy Stepanov -E: eugenis@google.com -D: MemorySanitizer, Android port of sanitizers - -N: Dmitry Vyukov -E: dvyukov@google.com -D: ThreadSanitizer - -N: Bill Wendling -E: isanbard@gmail.com -D: Profile runtime library - -N: Christopher Apple, David Trevelyan -E: cja-private@pm.me, realtime.sanitizer@gmail.com -D: Realtime Sanitizer (RTSan) - -N: Alexander Shaposhnikov -E: alexander.v.shaposhnikov@gmail.com -D: Numerical Sanitizer (NSAN) diff --git a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake index b29ae179c2b4f..5a1e8db61023b 100644 --- a/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake +++ b/compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake @@ -102,7 +102,7 @@ if(APPLE) set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM64}) else() set(ALL_XRAY_SUPPORTED_ARCH ${X86_64} ${ARM32} ${ARM64} ${MIPS32} ${MIPS64} - powerpc64le ${HEXAGON} ${LOONGARCH64}) + powerpc64le ${HEXAGON} ${LOONGARCH64} ${RISCV32} ${RISCV64}) endif() set(ALL_XRAY_DSO_SUPPORTED_ARCH ${X86_64} ${ARM64}) set(ALL_SHADOWCALLSTACK_SUPPORTED_ARCH ${ARM64}) diff --git a/compiler-rt/include/sanitizer/memprof_interface.h b/compiler-rt/include/sanitizer/memprof_interface.h index 4660a7818c92b..6d9b2a2394f41 100644 --- a/compiler-rt/include/sanitizer/memprof_interface.h +++ b/compiler-rt/include/sanitizer/memprof_interface.h @@ -47,9 +47,9 @@ void SANITIZER_CDECL __memprof_print_accumulated_stats(void); /// User-provided default option settings. /// -/// You can provide your own implementation of this function to return a string -/// containing MemProf runtime options (for example, -/// verbosity=1:print_stats=1). +/// You can set these options via the -memprof-runtime-default-options LLVM flag +/// or you can provide your own implementation of this function. See +/// memprof_flags.h for more info. /// /// \returns Default options string. const char *SANITIZER_CDECL __memprof_default_options(void); diff --git a/compiler-rt/lib/asan/asan_flags.cpp b/compiler-rt/lib/asan/asan_flags.cpp index 56deb1b0d082b..9cfb70bd00c78 100644 --- a/compiler-rt/lib/asan/asan_flags.cpp +++ b/compiler-rt/lib/asan/asan_flags.cpp @@ -240,6 +240,13 @@ void InitializeFlags() { DisplayHelpMessages(&asan_parser); ProcessFlags(); + + // TODO: Update other globals and data structures that may need to change + // after initialization due to new flags potentially being set changing after + // `__asan_default_options` is registered. + // See GH issue 'https://github.com/llvm/llvm-project/issues/117925' for + // details. + SetAllocatorMayReturnNull(common_flags()->allocator_may_return_null); }); # if CAN_SANITIZE_UB diff --git a/compiler-rt/lib/asan/asan_interceptors.cpp b/compiler-rt/lib/asan/asan_interceptors.cpp index 4129ee8076122..e6c95dfb82c32 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cpp +++ b/compiler-rt/lib/asan/asan_interceptors.cpp @@ -85,7 +85,7 @@ int OnExit() { // ---------------------- Wrappers ---------------- {{{1 using namespace __asan; -DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr) +DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, usize) DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) #define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \ @@ -529,13 +529,13 @@ DEFINE_REAL(char*, index, const char *string, int c) return REAL(strcat)(to, from); } -INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { +INTERCEPTOR(char*, strncat, char *to, const char *from, usize size) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strncat); AsanInitFromRtl(); if (flags()->replace_str) { uptr from_length = MaybeRealStrnlen(from, size); - uptr copy_length = Min(size, from_length + 1); + uptr copy_length = Min(size, from_length + 1); ASAN_READ_RANGE(ctx, from, copy_length); uptr to_length = internal_strlen(to); ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length); @@ -617,12 +617,12 @@ INTERCEPTOR(char*, __strdup, const char *s) { } #endif // ASAN_INTERCEPT___STRDUP -INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { +INTERCEPTOR(char*, strncpy, char *to, const char *from, usize size) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strncpy); AsanInitFromRtl(); if (flags()->replace_str) { - uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1); + uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1); CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size); ASAN_READ_RANGE(ctx, from, from_size); ASAN_WRITE_RANGE(ctx, to, size); diff --git a/compiler-rt/lib/asan/asan_interceptors.h b/compiler-rt/lib/asan/asan_interceptors.h index 826b45f5ada8c..3e2386eaf8092 100644 --- a/compiler-rt/lib/asan/asan_interceptors.h +++ b/compiler-rt/lib/asan/asan_interceptors.h @@ -124,11 +124,11 @@ void InitializePlatformInterceptors(); # define ASAN_INTERCEPT_PTHREAD_ATFORK 0 #endif -DECLARE_REAL(int, memcmp, const void *a1, const void *a2, uptr size) +DECLARE_REAL(int, memcmp, const void *a1, const void *a2, SIZE_T size) DECLARE_REAL(char*, strchr, const char *str, int c) DECLARE_REAL(SIZE_T, strlen, const char *s) -DECLARE_REAL(char*, strncpy, char *to, const char *from, uptr size) -DECLARE_REAL(uptr, strnlen, const char *s, uptr maxlen) +DECLARE_REAL(char*, strncpy, char *to, const char *from, SIZE_T size) +DECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen) DECLARE_REAL(char*, strstr, const char *s1, const char *s2) # if !SANITIZER_APPLE diff --git a/compiler-rt/lib/asan/asan_interceptors_memintrinsics.h b/compiler-rt/lib/asan/asan_interceptors_memintrinsics.h index eb44f8f2f729b..14727a5d665ed 100644 --- a/compiler-rt/lib/asan/asan_interceptors_memintrinsics.h +++ b/compiler-rt/lib/asan/asan_interceptors_memintrinsics.h @@ -18,8 +18,8 @@ #include "asan_mapping.h" #include "interception/interception.h" -DECLARE_REAL(void *, memcpy, void *to, const void *from, uptr size) -DECLARE_REAL(void *, memset, void *block, int c, uptr size) +DECLARE_REAL(void *, memcpy, void *to, const void *from, SIZE_T size) +DECLARE_REAL(void *, memset, void *block, int c, SIZE_T size) namespace __asan { diff --git a/compiler-rt/lib/builtins/CMakeLists.txt b/compiler-rt/lib/builtins/CMakeLists.txt index 73c1b5062ec9a..3a868c11e7288 100644 --- a/compiler-rt/lib/builtins/CMakeLists.txt +++ b/compiler-rt/lib/builtins/CMakeLists.txt @@ -572,9 +572,11 @@ set(aarch64_SOURCES aarch64/fp_mode.c ) +set(COMPILER_RT_AARCH64_FMV_USES_GLOBAL_CONSTRUCTOR NOT(FUCHSIA OR APPLE)) + if (COMPILER_RT_HAS_AARCH64_SME) - if (NOT COMPILER_RT_DISABLE_AARCH64_FMV AND COMPILER_RT_HAS_FNO_BUILTIN_FLAG AND (COMPILER_RT_HAS_AUXV OR COMPILER_RT_BAREMETAL_BUILD)) - list(APPEND aarch64_SOURCES aarch64/sme-abi.S aarch64/sme-libc-mem-routines.S aarch64/sme-abi-init.c aarch64/sme-abi-vg.c aarch64/sme-libc-routines.c) + if (NOT COMPILER_RT_DISABLE_AARCH64_FMV AND COMPILER_RT_HAS_FNO_BUILTIN_FLAG AND COMPILER_RT_AARCH64_FMV_USES_GLOBAL_CONSTRUCTOR) + list(APPEND aarch64_SOURCES aarch64/sme-abi.S aarch64/sme-libc-mem-routines.S aarch64/sme-abi-assert.c aarch64/sme-libc-routines.c) message(STATUS "AArch64 SME ABI routines enabled") set_source_files_properties(aarch64/sme-libc-routines.c PROPERTIES COMPILE_FLAGS "-fno-builtin") else() @@ -842,6 +844,8 @@ 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) endif() append_list_if(COMPILER_RT_HAS_ASM_LSE HAS_ASM_LSE BUILTIN_DEFS) diff --git a/compiler-rt/lib/builtins/aarch64/sme-abi-assert.c b/compiler-rt/lib/builtins/aarch64/sme-abi-assert.c new file mode 100644 index 0000000000000..4333353f8d2d1 --- /dev/null +++ b/compiler-rt/lib/builtins/aarch64/sme-abi-assert.c @@ -0,0 +1,10 @@ +// 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 + +// We rely on the FMV __aarch64_cpu_features mechanism to determine +// which features are set at runtime. + +#include "../cpu_model/AArch64CPUFeatures.inc" +_Static_assert(FEAT_SVE == 30, "sme-abi.S assumes FEAT_SVE = 30"); +_Static_assert(FEAT_SME == 42, "sme-abi.S assumes FEAT_SME = 42"); diff --git a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c b/compiler-rt/lib/builtins/aarch64/sme-abi-init.c deleted file mode 100644 index d3cd8278a5d21..0000000000000 --- a/compiler-rt/lib/builtins/aarch64/sme-abi-init.c +++ /dev/null @@ -1,50 +0,0 @@ -// 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 - -__attribute__((visibility("hidden"), nocommon)) -_Bool __aarch64_has_sme_and_tpidr2_el0; - -// We have multiple ways to check that the function has SME, depending on our -// target. -// * For Linux/Glibc we can use getauxval(). -// * For Android we can use getauxval(). -// * For newlib we can use __aarch64_sme_accessible(). - -#if defined(__linux__) - -#if defined(__ANDROID__) -#include -#elif __has_include() -#include -#else -#define getauxval(x) 0 -#endif -#include "../cpu_model/aarch64/hwcap.inc" - -static _Bool has_sme(void) { return getauxval(AT_HWCAP2) & HWCAP2_SME; } - -#else // defined(__linux__) - -#if defined(COMPILER_RT_SHARED_LIB) -__attribute__((weak)) -#endif -extern _Bool __aarch64_sme_accessible(void); - -static _Bool has_sme(void) { -#if defined(COMPILER_RT_SHARED_LIB) - if (!__aarch64_sme_accessible) - return 0; -#endif - return __aarch64_sme_accessible(); -} - -#endif // defined(__linux__) - -#if __GNUC__ >= 9 -#pragma GCC diagnostic ignored "-Wprio-ctor-dtor" -#endif -__attribute__((constructor(90))) -static void init_aarch64_has_sme(void) { - __aarch64_has_sme_and_tpidr2_el0 = has_sme(); -} diff --git a/compiler-rt/lib/builtins/aarch64/sme-abi-vg.c b/compiler-rt/lib/builtins/aarch64/sme-abi-vg.c deleted file mode 100644 index 4b9ee8c1d382d..0000000000000 --- a/compiler-rt/lib/builtins/aarch64/sme-abi-vg.c +++ /dev/null @@ -1,18 +0,0 @@ -// 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 "../cpu_model/aarch64.h" - -struct FEATURES { - unsigned long long features; -}; - -extern struct FEATURES __aarch64_cpu_features; - -CONSTRUCTOR_ATTRIBUTE static void get_aarch64_cpu_features(void) { - if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED)) - return; - - __init_cpu_features(); -} diff --git a/compiler-rt/lib/builtins/aarch64/sme-abi.S b/compiler-rt/lib/builtins/aarch64/sme-abi.S index 3e9bd2c23b2fc..a6bb921bd9e6b 100644 --- a/compiler-rt/lib/builtins/aarch64/sme-abi.S +++ b/compiler-rt/lib/builtins/aarch64/sme-abi.S @@ -8,17 +8,16 @@ #include "../assembly.h" +.set FEAT_SVE_BIT, 30 +.set FEAT_SME_BIT, 42 +.set SVCR_PSTATE_SM_BIT, 0 #if !defined(__APPLE__) -#define TPIDR2_SYMBOL SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0) -#define TPIDR2_SYMBOL_OFFSET :lo12:SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0) #define CPU_FEATS_SYMBOL SYMBOL_NAME(__aarch64_cpu_features) #define CPU_FEATS_SYMBOL_OFFSET :lo12:SYMBOL_NAME(__aarch64_cpu_features) #else // MachO requires @page/@pageoff directives because the global is defined // in a different file. Otherwise this file may fail to build. -#define TPIDR2_SYMBOL SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)@page -#define TPIDR2_SYMBOL_OFFSET SYMBOL_NAME(__aarch64_has_sme_and_tpidr2_el0)@pageoff #define CPU_FEATS_SYMBOL SYMBOL_NAME(__aarch64_cpu_features)@page #define CPU_FEATS_SYMBOL_OFFSET SYMBOL_NAME(__aarch64_cpu_features)@pageoff #endif @@ -61,9 +60,9 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_sme_state) mov x0, xzr mov x1, xzr - adrp x16, TPIDR2_SYMBOL - ldrb w16, [x16, TPIDR2_SYMBOL_OFFSET] - cbz w16, 1f + adrp x16, CPU_FEATS_SYMBOL + ldr x16, [x16, CPU_FEATS_SYMBOL_OFFSET] + tbz x16, #FEAT_SME_BIT, 1f 0: orr x0, x0, #0xC000000000000000 mrs x16, SVCR @@ -114,9 +113,9 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_tpidr2_save) BTI_C // If the current thread does not have access to TPIDR2_EL0, the subroutine // does nothing. - adrp x14, TPIDR2_SYMBOL - ldrb w14, [x14, TPIDR2_SYMBOL_OFFSET] - cbz w14, 1f + adrp x14, CPU_FEATS_SYMBOL + ldr x14, [x14, CPU_FEATS_SYMBOL_OFFSET] + tbz x14, #FEAT_SME_BIT, 1f // If TPIDR2_EL0 is null, the subroutine does nothing. mrs x16, TPIDR2_EL0 @@ -155,9 +154,9 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_za_disable) BTI_C // If the current thread does not have access to SME, the subroutine does // nothing. - adrp x14, TPIDR2_SYMBOL - ldrb w14, [x14, TPIDR2_SYMBOL_OFFSET] - cbz w14, 0f + adrp x14, CPU_FEATS_SYMBOL + ldr x14, [x14, CPU_FEATS_SYMBOL_OFFSET] + tbz x14, #FEAT_SME_BIT, 0f // Otherwise, the subroutine behaves as if it did the following: // * Call __arm_tpidr2_save. @@ -188,39 +187,18 @@ DEFINE_COMPILERRT_OUTLINE_FUNCTION_UNMANGLED(__arm_get_current_vg) .variant_pcs __arm_get_current_vg BTI_C - stp x29, x30, [sp, #-16]! - .cfi_def_cfa_offset 16 - mov x29, sp - .cfi_def_cfa w29, 16 - .cfi_offset w30, -8 - .cfi_offset w29, -16 adrp x17, CPU_FEATS_SYMBOL - ldr w17, [x17, CPU_FEATS_SYMBOL_OFFSET] - tbnz w17, #30, 0f - adrp x16, TPIDR2_SYMBOL - ldrb w16, [x16, TPIDR2_SYMBOL_OFFSET] - cbz w16, 1f + ldr x17, [x17, CPU_FEATS_SYMBOL_OFFSET] + tbnz w17, #FEAT_SVE_BIT, 1f + tbz x17, #FEAT_SME_BIT, 2f 0: - mov x18, x1 - bl __arm_sme_state - mov x1, x18 - and x17, x17, #0x40000000 - bfxil x17, x0, #0, #1 - cbz x17, 1f + mrs x17, SVCR + tbz x17, #SVCR_PSTATE_SM_BIT, 2f +1: cntd x0 - .cfi_def_cfa wsp, 16 - ldp x29, x30, [sp], #16 - .cfi_def_cfa_offset 0 - .cfi_restore w30 - .cfi_restore w29 ret -1: +2: mov x0, xzr - .cfi_def_cfa wsp, 16 - ldp x29, x30, [sp], #16 - .cfi_def_cfa_offset 0 - .cfi_restore w30 - .cfi_restore w29 ret END_COMPILERRT_OUTLINE_FUNCTION(__arm_get_current_vg) diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64.c b/compiler-rt/lib/builtins/cpu_model/aarch64.c index 74e5e01b66c54..4082fd62ea11a 100644 --- a/compiler-rt/lib/builtins/cpu_model/aarch64.c +++ b/compiler-rt/lib/builtins/cpu_model/aarch64.c @@ -80,6 +80,8 @@ struct { #include "aarch64/fmv/getauxval.inc" #elif defined(_WIN32) #include "aarch64/fmv/windows.inc" +#elif defined(ENABLE_BAREMETAL_AARCH64_FMV) +#include "aarch64/fmv/baremetal.inc" #else #include "aarch64/fmv/unimplemented.inc" #endif diff --git a/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/baremetal.inc b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/baremetal.inc new file mode 100644 index 0000000000000..f188e84808e01 --- /dev/null +++ b/compiler-rt/lib/builtins/cpu_model/aarch64/fmv/baremetal.inc @@ -0,0 +1,31 @@ +// For baremetal platforms, we don't really initialise '__aarch64_cpu_features', +// with exception of FEAT_SME that we can get from '__aarch64_sme_accessible'. + +#if defined(COMPILER_RT_SHARED_LIB) +__attribute__((weak)) +#endif +extern _Bool +__aarch64_sme_accessible(void); + +static _Bool has_sme(void) { +#if defined(COMPILER_RT_SHARED_LIB) + if (!__aarch64_sme_accessible) + return 0; +#endif + return __aarch64_sme_accessible(); +} + +void __init_cpu_features_resolver(unsigned long hwcap, + const __ifunc_arg_t *arg) {} + +void CONSTRUCTOR_ATTRIBUTE __init_cpu_features(void) { + // CPU features already initialized. + if (__atomic_load_n(&__aarch64_cpu_features.features, __ATOMIC_RELAXED)) + return; + + unsigned long long feat = 0; + if (has_sme()) + feat |= 1ULL << FEAT_SME; + + __atomic_store_n(&__aarch64_cpu_features.features, feat, __ATOMIC_RELAXED); +} diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h index 0580d97edda68..3cb6b446638e0 100644 --- a/compiler-rt/lib/interception/interception.h +++ b/compiler-rt/lib/interception/interception.h @@ -37,7 +37,7 @@ #endif #define SIZE_T __sanitizer::usize -#define SSIZE_T __sanitizer::sptr +#define SSIZE_T __sanitizer::ssize typedef __sanitizer::sptr PTRDIFF_T; typedef __sanitizer::s64 INTMAX_T; typedef __sanitizer::u64 UINTMAX_T; diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp index dc3018a675dee..a5897274521e9 100644 --- a/compiler-rt/lib/interception/interception_win.cpp +++ b/compiler-rt/lib/interception/interception_win.cpp @@ -418,7 +418,7 @@ static void *AllocateTrampolineRegion(uptr min_addr, uptr max_addr, ReportError( "interception_win: AllocateTrampolineRegion failed to find free memory; " "min_addr: %p, max_addr: %p, func_addr: %p, granularity: %zu\n", - (void *)min_addr, (void *)max_addr, granularity); + (void *)min_addr, (void *)max_addr, (void *)func_addr, granularity); return nullptr; #else return ::VirtualAlloc(nullptr, @@ -634,15 +634,17 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0xD284: // 84 D2 : test dl,dl return 2; + case 0xE483: // 83 E4 XX : and esp, XX + case 0xEC83: // 83 EC XX : sub esp, XX + case 0xC1F6: // F6 C1 XX : test cl, XX + return 3; + // Cannot overwrite control-instruction. Return 0 to indicate failure. case 0x25FF: // FF 25 XX YY ZZ WW : jmp dword ptr ds:[WWZZYYXX] return 0; } - switch (0x00FFFFFF & *(u32*)address) { - case 0xF8E483: // 83 E4 F8 : and esp, 0xFFFFFFF8 - case 0x64EC83: // 83 EC 64 : sub esp, 64h - return 3; + switch (0x00FFFFFF & *(u32 *)address) { case 0x24A48D: // 8D A4 24 XX XX XX XX : lea esp, [esp + XX XX XX XX] return 7; } @@ -723,8 +725,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { return 7; } - switch (0x00FFFFFF & *(u32*)address) { - case 0x07c1f6: // f6 c1 07 : test cl, 0x7 + switch (0x00FFFFFF & *(u32 *)address) { case 0x10b70f: // 0f b7 10 : movzx edx, WORD PTR [rax] case 0xc00b4d: // 4d 0b c0 : or r8, r8 case 0xc03345: // 45 33 c0 : xor r8d, r8d @@ -772,7 +773,6 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0xdb8548: // 48 85 db : test rbx, rbx case 0xdb854d: // 4d 85 db : test r11, r11 case 0xdc8b4c: // 4c 8b dc : mov r11, rsp - case 0xe0e483: // 83 e4 e0 : and esp, 0xFFFFFFE0 case 0xe48548: // 48 85 e4 : test rsp, rsp case 0xe4854d: // 4d 85 e4 : test r12, r12 case 0xe58948: // 48 89 e5 : mov rbp, rsp @@ -808,7 +808,6 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0x798141: // 41 81 79 XX YY YY YY YY : cmp DWORD PTR [r9+YY], XX XX XX XX case 0x7a8141: // 41 81 7a XX YY YY YY YY : cmp DWORD PTR [r10+YY], XX XX XX XX case 0x7b8141: // 41 81 7b XX YY YY YY YY : cmp DWORD PTR [r11+YY], XX XX XX XX - case 0x7c8141: // 41 81 7c XX YY YY YY YY : cmp DWORD PTR [r12+YY], XX XX XX XX case 0x7d8141: // 41 81 7d XX YY YY YY YY : cmp DWORD PTR [r13+YY], XX XX XX XX case 0x7e8141: // 41 81 7e XX YY YY YY YY : cmp DWORD PTR [r14+YY], XX XX XX XX case 0x7f8141: // 41 81 7f YY XX XX XX XX : cmp DWORD PTR [r15+YY], XX XX XX XX @@ -835,6 +834,10 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0x2444c7: // C7 44 24 XX YY YY YY YY // mov dword ptr [rsp + XX], YYYYYYYY return 8; + + case 0x7c8141: // 41 81 7c ZZ YY XX XX XX XX + // cmp DWORD PTR [reg+reg*n+YY], XX XX XX XX + return 9; } switch (*(u32*)(address)) { @@ -868,7 +871,6 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0x5D8B: // 8B 5D XX : mov ebx, dword ptr [ebp + XX] case 0x7D8B: // 8B 7D XX : mov edi, dword ptr [ebp + XX] case 0x758B: // 8B 75 XX : mov esi, dword ptr [ebp + XX] - case 0xEC83: // 83 EC XX : sub esp, XX case 0x75FF: // FF 75 XX : push dword ptr [ebp + XX] return 3; case 0xC1F7: // F7 C1 XX YY ZZ WW : test ecx, WWZZYYXX @@ -1247,7 +1249,7 @@ uptr InternalGetProcAddress(void *module, const char *func_name) { char function_name[256]; size_t funtion_name_length = _strlen(func); if (funtion_name_length >= sizeof(function_name) - 1) { - ReportError("interception_win: func too long: '%s'\n", func); + ReportError("interception_win: func too long: '%s'\n", (char *)func); InterceptionFailed(); } diff --git a/compiler-rt/lib/interception/tests/interception_win_test.cpp b/compiler-rt/lib/interception/tests/interception_win_test.cpp index 3c60d9c6f49df..04d9a6766f65a 100644 --- a/compiler-rt/lib/interception/tests/interception_win_test.cpp +++ b/compiler-rt/lib/interception/tests/interception_win_test.cpp @@ -852,6 +852,8 @@ const struct InstructionSizeData { { 2, {0x8B, 0xC1}, 0, "8B C1 : mov eax, ecx"}, { 2, {0x8B, 0xEC}, 0, "8B EC : mov ebp, esp"}, { 2, {0x8B, 0xFF}, 0, "8B FF : mov edi, edi"}, + { 3, {0x83, 0xE4, 0x72}, 0, "83 E4 XX : and esp, XX"}, + { 3, {0x83, 0xEC, 0x72}, 0, "83 EC XX : sub esp, XX"}, { 3, {0xc2, 0x71, 0x72}, 0, "C2 XX XX : ret XX (needed for registering weak functions)"}, { 5, {0x68, 0x71, 0x72, 0x73, 0x74}, 0, "68 XX XX XX XX : push imm32"}, { 5, {0xb8, 0x71, 0x72, 0x73, 0x74}, 0, "b8 XX XX XX XX : mov eax, XX XX XX XX"}, @@ -927,6 +929,7 @@ const struct InstructionSizeData { { 3, {0x4d, 0x85, 0xed}, 0, "4d 85 ed : test r13, r13"}, { 3, {0x4d, 0x85, 0xf6}, 0, "4d 85 f6 : test r14, r14"}, { 3, {0x4d, 0x85, 0xff}, 0, "4d 85 ff : test r15, r15"}, + { 3, {0xf6, 0xc1, 0x72}, 0, "f6 c1 XX : test cl, XX"}, { 4, {0x44, 0x0f, 0xb6, 0x1a}, 0, "44 0f b6 1a : movzx r11d, BYTE PTR [rdx]"}, { 4, {0x44, 0x8d, 0x42, 0x73}, 0, "44 8d 42 XX : lea r8d , [rdx + XX]"}, { 4, {0x48, 0x83, 0xec, 0x73}, 0, "48 83 ec XX : sub rsp, XX"}, @@ -989,6 +992,7 @@ const struct InstructionSizeData { { 8, {0x41, 0x81, 0x7f, 0x73, 0x74, 0x75, 0x76, 0x77}, 0, "41 81 7f YY XX XX XX XX : cmp DWORD PTR [r15+YY], XX XX XX XX"}, { 8, {0x81, 0x7c, 0x24, 0x73, 0x74, 0x75, 0x76, 0x77}, 0, "81 7c 24 YY XX XX XX XX : cmp DWORD PTR [rsp+YY], XX XX XX XX"}, { 8, {0xc7, 0x44, 0x24, 0x73, 0x74, 0x75, 0x76, 0x77}, 0, "C7 44 24 XX YY YY YY YY : mov dword ptr [rsp + XX], YYYYYYYY"}, + { 9, {0x41, 0x81, 0x7c, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78}, 0, "41 81 7c ZZ YY XX XX XX XX : cmp DWORD PTR [reg+reg*n+YY], XX XX XX XX"}, { 9, {0xA1, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78}, 0, "A1 XX XX XX XX XX XX XX XX : movabs eax, dword ptr ds:[XXXXXXXX]"}, #else // sorted list diff --git a/compiler-rt/lib/memprof/memprof_allocator.cpp b/compiler-rt/lib/memprof/memprof_allocator.cpp index 19b2b90106824..c3448c22532bb 100644 --- a/compiler-rt/lib/memprof/memprof_allocator.cpp +++ b/compiler-rt/lib/memprof/memprof_allocator.cpp @@ -301,7 +301,8 @@ struct Allocator { ~Allocator() { atomic_store_relaxed(&destructing, 1); - FinishAndWrite(); + if (flags()->dump_at_exit) + FinishAndWrite(); } static void PrintCallback(const uptr Key, LockedMemInfoBlock *const &Value, diff --git a/compiler-rt/lib/memprof/memprof_flags.cpp b/compiler-rt/lib/memprof/memprof_flags.cpp index b107ff8fa0a7c..95fde9d9672d6 100644 --- a/compiler-rt/lib/memprof/memprof_flags.cpp +++ b/compiler-rt/lib/memprof/memprof_flags.cpp @@ -89,5 +89,5 @@ void InitializeFlags() { } // namespace __memprof SANITIZER_INTERFACE_WEAK_DEF(const char *, __memprof_default_options, void) { - return ""; + return __memprof_default_options_str; } diff --git a/compiler-rt/lib/memprof/memprof_flags.h b/compiler-rt/lib/memprof/memprof_flags.h index 2f2b628653dc1..4dd395a6be94a 100644 --- a/compiler-rt/lib/memprof/memprof_flags.h +++ b/compiler-rt/lib/memprof/memprof_flags.h @@ -17,13 +17,15 @@ #include "sanitizer_common/sanitizer_flag_parser.h" #include "sanitizer_common/sanitizer_internal_defs.h" -// MemProf flag values can be defined in four ways: -// 1) initialized with default values at startup. -// 2) overriden during compilation of MemProf runtime by providing -// compile definition MEMPROF_DEFAULT_OPTIONS. -// 3) overriden from string returned by user-specified function -// __memprof_default_options(). -// 4) overriden from env variable MEMPROF_OPTIONS. +// Default MemProf flags are defined in memprof_flags.inc and sancov_flags.inc. +// These values can be overridded in a number of ways, each option overrides the +// prior one: +// 1) by setting MEMPROF_DEFAULT_OPTIONS during the compilation of the MemProf +// runtime +// 2) by setting the LLVM flag -memprof-runtime-default-options during the +// compilation of your binary +// 3) by overriding the user-specified function __memprof_default_options() +// 4) by setting the environment variable MEMPROF_OPTIONS during runtime namespace __memprof { diff --git a/compiler-rt/lib/memprof/memprof_flags.inc b/compiler-rt/lib/memprof/memprof_flags.inc index 7c5dc091f7935..1d8e77752caa5 100644 --- a/compiler-rt/lib/memprof/memprof_flags.inc +++ b/compiler-rt/lib/memprof/memprof_flags.inc @@ -38,4 +38,7 @@ MEMPROF_FLAG(bool, allocator_frees_and_returns_null_on_realloc_zero, true, MEMPROF_FLAG(bool, print_text, false, "If set, prints the heap profile in text format. Else use the raw binary serialization format.") MEMPROF_FLAG(bool, print_terse, false, - "If set, prints memory profile in a terse format. Only applicable if print_text = true.") \ No newline at end of file + "If set, prints memory profile in a terse format. Only applicable " + "if print_text = true.") +MEMPROF_FLAG(bool, dump_at_exit, true, + "If set, dump profiles when the program terminates.") diff --git a/compiler-rt/lib/memprof/memprof_interceptors.cpp b/compiler-rt/lib/memprof/memprof_interceptors.cpp index 53ee4e953419b..f4d7fd46e6198 100644 --- a/compiler-rt/lib/memprof/memprof_interceptors.cpp +++ b/compiler-rt/lib/memprof/memprof_interceptors.cpp @@ -49,7 +49,7 @@ int OnExit() { // ---------------------- Wrappers ---------------- {{{1 using namespace __memprof; -DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr) +DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, usize) DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) #define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \ @@ -185,12 +185,12 @@ INTERCEPTOR(char *, strcat, char *to, const char *from) { return REAL(strcat)(to, from); } -INTERCEPTOR(char *, strncat, char *to, const char *from, uptr size) { +INTERCEPTOR(char *, strncat, char *to, const char *from, usize size) { void *ctx; MEMPROF_INTERCEPTOR_ENTER(ctx, strncat); ENSURE_MEMPROF_INITED(); uptr from_length = MaybeRealStrnlen(from, size); - uptr copy_length = Min(size, from_length + 1); + uptr copy_length = Min(size, from_length + 1); MEMPROF_READ_RANGE(from, copy_length); uptr to_length = internal_strlen(to); MEMPROF_READ_STRING(to, to_length); @@ -239,11 +239,11 @@ INTERCEPTOR(char *, __strdup, const char *s) { return reinterpret_cast(new_mem); } -INTERCEPTOR(char *, strncpy, char *to, const char *from, uptr size) { +INTERCEPTOR(char *, strncpy, char *to, const char *from, usize size) { void *ctx; MEMPROF_INTERCEPTOR_ENTER(ctx, strncpy); ENSURE_MEMPROF_INITED(); - uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1); + uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1); MEMPROF_READ_RANGE(from, from_size); MEMPROF_WRITE_RANGE(to, size); return REAL(strncpy)(to, from, size); diff --git a/compiler-rt/lib/memprof/memprof_interceptors.h b/compiler-rt/lib/memprof/memprof_interceptors.h index 20edef42a5150..53d685706b849 100644 --- a/compiler-rt/lib/memprof/memprof_interceptors.h +++ b/compiler-rt/lib/memprof/memprof_interceptors.h @@ -33,11 +33,11 @@ void InitializePlatformInterceptors(); } // namespace __memprof -DECLARE_REAL(int, memcmp, const void *a1, const void *a2, uptr size) +DECLARE_REAL(int, memcmp, const void *a1, const void *a2, SIZE_T size) DECLARE_REAL(char *, strchr, const char *str, int c) DECLARE_REAL(SIZE_T, strlen, const char *s) -DECLARE_REAL(char *, strncpy, char *to, const char *from, uptr size) -DECLARE_REAL(uptr, strnlen, const char *s, uptr maxlen) +DECLARE_REAL(char *, strncpy, char *to, const char *from, SIZE_T size) +DECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen) DECLARE_REAL(char *, strstr, const char *s1, const char *s2) #define MEMPROF_INTERCEPT_FUNC(name) \ diff --git a/compiler-rt/lib/memprof/memprof_interceptors_memintrinsics.h b/compiler-rt/lib/memprof/memprof_interceptors_memintrinsics.h index 0b87a6f3522af..99b6ccae126e1 100644 --- a/compiler-rt/lib/memprof/memprof_interceptors_memintrinsics.h +++ b/compiler-rt/lib/memprof/memprof_interceptors_memintrinsics.h @@ -18,8 +18,8 @@ #include "memprof_internal.h" #include "memprof_mapping.h" -DECLARE_REAL(void *, memcpy, void *to, const void *from, uptr size) -DECLARE_REAL(void *, memset, void *block, int c, uptr size) +DECLARE_REAL(void *, memcpy, void *to, const void *from, SIZE_T size) +DECLARE_REAL(void *, memset, void *block, int c, SIZE_T size) namespace __memprof { diff --git a/compiler-rt/lib/memprof/memprof_interface_internal.h b/compiler-rt/lib/memprof/memprof_interface_internal.h index 318bc41044056..7d3a937814a34 100644 --- a/compiler-rt/lib/memprof/memprof_interface_internal.h +++ b/compiler-rt/lib/memprof/memprof_interface_internal.h @@ -40,6 +40,9 @@ void __memprof_record_access_range(void const volatile *addr, uptr size); SANITIZER_INTERFACE_ATTRIBUTE void __memprof_print_accumulated_stats(); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE extern char + __memprof_default_options_str[1]; + SANITIZER_INTERFACE_ATTRIBUTE const char *__memprof_default_options(); diff --git a/compiler-rt/lib/memprof/memprof_rtl.cpp b/compiler-rt/lib/memprof/memprof_rtl.cpp index 2cc6c2df5a6fe..ef8884a7e56f4 100644 --- a/compiler-rt/lib/memprof/memprof_rtl.cpp +++ b/compiler-rt/lib/memprof/memprof_rtl.cpp @@ -27,6 +27,8 @@ #include +SANITIZER_WEAK_ATTRIBUTE char __memprof_default_options_str[1]; + uptr __memprof_shadow_memory_dynamic_address; // Global interface symbol. // Allow the user to specify a profile output file via the binary. diff --git a/compiler-rt/lib/memprof/weak_symbols.txt b/compiler-rt/lib/memprof/weak_symbols.txt index 271813612ab60..bfece89e2e157 100644 --- a/compiler-rt/lib/memprof/weak_symbols.txt +++ b/compiler-rt/lib/memprof/weak_symbols.txt @@ -1 +1 @@ -___memprof_default_options __memprof_profile_filename +___memprof_default_options_str ___memprof_default_options __memprof_profile_filename diff --git a/compiler-rt/lib/msan/msan_interceptors.cpp b/compiler-rt/lib/msan/msan_interceptors.cpp index f05c20618780b..76255cdb742a3 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cpp +++ b/compiler-rt/lib/msan/msan_interceptors.cpp @@ -59,8 +59,8 @@ using __sanitizer::atomic_uintptr_t; DECLARE_REAL(SIZE_T, strlen, const char *s) DECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen) -DECLARE_REAL(void *, memcpy, void *dest, const void *src, uptr n) -DECLARE_REAL(void *, memset, void *dest, int c, uptr n) +DECLARE_REAL(void *, memcpy, void *dest, const void *src, SIZE_T n) +DECLARE_REAL(void *, memset, void *dest, int c, SIZE_T n) // True if this is a nested interceptor. static THREADLOCAL int in_interceptor_scope; diff --git a/compiler-rt/lib/msan/msan_poisoning.cpp b/compiler-rt/lib/msan/msan_poisoning.cpp index 1889e980bfc0e..ac403681af406 100644 --- a/compiler-rt/lib/msan/msan_poisoning.cpp +++ b/compiler-rt/lib/msan/msan_poisoning.cpp @@ -17,9 +17,9 @@ #include "msan_thread.h" #include "sanitizer_common/sanitizer_common.h" -DECLARE_REAL(void *, memset, void *dest, int c, uptr n) -DECLARE_REAL(void *, memcpy, void *dest, const void *src, uptr n) -DECLARE_REAL(void *, memmove, void *dest, const void *src, uptr n) +DECLARE_REAL(void *, memset, void *dest, int c, SIZE_T n) +DECLARE_REAL(void *, memcpy, void *dest, const void *src, SIZE_T n) +DECLARE_REAL(void *, memmove, void *dest, const void *src, SIZE_T n) namespace __msan { diff --git a/compiler-rt/lib/nsan/nsan_allocator.cpp b/compiler-rt/lib/nsan/nsan_allocator.cpp index 19004ad7dc8db..128d37f52ba3c 100644 --- a/compiler-rt/lib/nsan/nsan_allocator.cpp +++ b/compiler-rt/lib/nsan/nsan_allocator.cpp @@ -25,8 +25,8 @@ using namespace __nsan; -DECLARE_REAL(void *, memcpy, void *dest, const void *src, uptr n) -DECLARE_REAL(void *, memset, void *dest, int c, uptr n) +DECLARE_REAL(void *, memcpy, void *dest, const void *src, SIZE_T n) +DECLARE_REAL(void *, memset, void *dest, int c, SIZE_T n) namespace { struct Metadata { diff --git a/compiler-rt/lib/nsan/nsan_interceptors.cpp b/compiler-rt/lib/nsan/nsan_interceptors.cpp index 5f25eba856070..2549f492b736a 100644 --- a/compiler-rt/lib/nsan/nsan_interceptors.cpp +++ b/compiler-rt/lib/nsan/nsan_interceptors.cpp @@ -28,7 +28,7 @@ using namespace __sanitizer; template T min(T a, T b) { return a < b ? a : b; } -INTERCEPTOR(void *, memset, void *dst, int v, uptr size) { +INTERCEPTOR(void *, memset, void *dst, int v, usize size) { // NOTE: This guard is needed because nsan's initialization code might call // memset. if (!nsan_initialized && REAL(memset) == nullptr) @@ -39,13 +39,13 @@ INTERCEPTOR(void *, memset, void *dst, int v, uptr size) { return res; } -INTERCEPTOR(wchar_t *, wmemset, wchar_t *dst, wchar_t v, uptr size) { +INTERCEPTOR(wchar_t *, wmemset, wchar_t *dst, wchar_t v, usize size) { wchar_t *res = REAL(wmemset)(dst, v, size); __nsan_set_value_unknown((u8 *)dst, sizeof(wchar_t) * size); return res; } -INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) { +INTERCEPTOR(void *, memmove, void *dst, const void *src, usize size) { // NOTE: This guard is needed because nsan's initialization code might call // memmove. if (!nsan_initialized && REAL(memmove) == nullptr) @@ -57,13 +57,13 @@ INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) { return res; } -INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dst, const wchar_t *src, uptr size) { +INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dst, const wchar_t *src, usize size) { wchar_t *res = REAL(wmemmove)(dst, src, size); __nsan_copy_values((u8 *)dst, (const u8 *)src, sizeof(wchar_t) * size); return res; } -INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) { +INTERCEPTOR(void *, memcpy, void *dst, const void *src, usize size) { // NOTE: This guard is needed because nsan's initialization code might call // memcpy. if (!nsan_initialized && REAL(memcpy) == nullptr) { @@ -78,7 +78,7 @@ INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) { return res; } -INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dst, const wchar_t *src, uptr size) { +INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dst, const wchar_t *src, usize size) { wchar_t *res = REAL(wmemcpy)(dst, src, size); __nsan_copy_values((u8 *)dst, (const u8 *)src, sizeof(wchar_t) * size); return res; @@ -136,7 +136,7 @@ INTERCEPTOR(wchar_t *, wcsdup, const wchar_t *S) { return res; } -INTERCEPTOR(char *, strndup, const char *S, uptr size) { +INTERCEPTOR(char *, strndup, const char *S, usize size) { char *res = REAL(strndup)(S, size); if (res) { nsanCopyZeroTerminated(res, S, min(internal_strlen(S), size)); @@ -156,7 +156,7 @@ INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dst, const wchar_t *src) { return res; } -INTERCEPTOR(char *, strncpy, char *dst, const char *src, uptr size) { +INTERCEPTOR(char *, strncpy, char *dst, const char *src, usize size) { char *res = REAL(strncpy)(dst, src, size); nsanCopyZeroTerminated(dst, src, min(size, internal_strlen(src))); return res; @@ -176,7 +176,7 @@ INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) { return res; } -INTERCEPTOR(char *, strncat, char *dst, const char *src, uptr size) { +INTERCEPTOR(char *, strncat, char *dst, const char *src, usize size) { const auto DstLen = internal_strlen(dst); char *res = REAL(strncat)(dst, src, size); nsanCopyZeroTerminated(dst + DstLen, src, min(size, internal_strlen(src))); @@ -195,11 +195,10 @@ INTERCEPTOR(wchar_t *, wcpcpy, wchar_t *dst, const wchar_t *src) { return res; } -INTERCEPTOR(uptr, strxfrm, char *dst, const char *src, uptr size) { +INTERCEPTOR(usize, strxfrm, char *dst, const char *src, usize size) { // This is overly conservative, but this function should very rarely be used. __nsan_set_value_unknown(reinterpret_cast(dst), internal_strlen(dst)); - const uptr res = REAL(strxfrm)(dst, src, size); - return res; + return REAL(strxfrm)(dst, src, size); } extern "C" int pthread_attr_init(void *attr); diff --git a/compiler-rt/lib/orc/CMakeLists.txt b/compiler-rt/lib/orc/CMakeLists.txt index 36f4349a240e3..7da230d8296e9 100644 --- a/compiler-rt/lib/orc/CMakeLists.txt +++ b/compiler-rt/lib/orc/CMakeLists.txt @@ -3,10 +3,11 @@ # ORC runtime library common implementation files. set(ORC_COMMON_SOURCES debug.cpp + dlfcn_wrapper.cpp extensible_rtti.cpp log_error_to_stderr.cpp run_program_wrapper.cpp - dlfcn_wrapper.cpp + resolve.cpp ) # Common implementation headers will go here. @@ -51,6 +52,8 @@ if (APPLE) set(ORC_ASM_SOURCES macho_tlv.x86-64.S macho_tlv.arm64.S + sysv_reenter.arm64.S + sysv_reenter.x86-64.S ) set(ORC_IMPL_HEADERS @@ -116,6 +119,8 @@ else() # not Apple elfnix_tls.x86-64.S elfnix_tls.aarch64.S elfnix_tls.ppc64.S + sysv_reenter.arm64.S + sysv_reenter.x86-64.S ) endif() diff --git a/compiler-rt/lib/orc/macho_tlv.x86-64.S b/compiler-rt/lib/orc/macho_tlv.x86-64.S index e3daf23e3029e..04b5bd7eba676 100644 --- a/compiler-rt/lib/orc/macho_tlv.x86-64.S +++ b/compiler-rt/lib/orc/macho_tlv.x86-64.S @@ -1,4 +1,4 @@ -//===-- orc_rt_macho_tlv.x86-64.s -------------------------------*- ASM -*-===// +//===-- macho_tlv.x86-64.s --------------------------------------*- ASM -*-===// // // 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/compiler-rt/lib/orc/resolve.cpp b/compiler-rt/lib/orc/resolve.cpp new file mode 100644 index 0000000000000..3d9b37d14d2a4 --- /dev/null +++ b/compiler-rt/lib/orc/resolve.cpp @@ -0,0 +1,49 @@ +//===- resolve.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 +// +//===----------------------------------------------------------------------===// +// +// This file contains a generic "resolver" function compatible with the +// __orc_rt_reenter function. +// +//===----------------------------------------------------------------------===// + +#include "executor_symbol_def.h" +#include "jit_dispatch.h" +#include "wrapper_function_utils.h" + +#include + +#define DEBUG_TYPE "resolve" + +using namespace orc_rt; + +// Declare function tags for functions in the JIT process. +ORC_RT_JIT_DISPATCH_TAG(__orc_rt_resolve_tag) + +// FIXME: Make this configurable via an alias. +static void __orc_rt_resolve_fail(void *Caller, const char *ErrMsg) { + fprintf(stderr, "error resolving implementation for stub %p: %s\n", Caller, + ErrMsg); + abort(); +} + +extern "C" ORC_RT_HIDDEN void *__orc_rt_resolve(void *Caller) { + Expected Result((ExecutorSymbolDef())); + if (auto Err = WrapperFunction( + SPSExecutorAddr)>::call(JITDispatch(&__orc_rt_resolve_tag), Result, + ExecutorAddr::fromPtr(Caller))) { + __orc_rt_resolve_fail(Caller, toString(std::move(Err)).c_str()); + return nullptr; // Unreachable. + } + + if (!Result) { + __orc_rt_resolve_fail(Caller, toString(Result.takeError()).c_str()); + return nullptr; // Unreachable. + } + + return Result->getAddress().toPtr(); +} diff --git a/compiler-rt/lib/orc/sysv_reenter.arm64.S b/compiler-rt/lib/orc/sysv_reenter.arm64.S new file mode 100644 index 0000000000000..74941c459d6ac --- /dev/null +++ b/compiler-rt/lib/orc/sysv_reenter.arm64.S @@ -0,0 +1,102 @@ +//===-- sysv_reenter.arm64.s ------------------------------------*- ASM -*-===// +// +// 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 is a part of the ORC runtime support library. +// +//===----------------------------------------------------------------------===// + +// The content of this file is arm64-only +#if defined(__arm64__) || defined(__aarch64__) + + .text + + // Saves GPRs, calls __orc_rt_resolve + .globl __orc_rt_sysv_reenter +__orc_rt_sysv_reenter: + // Save register state, set up new stack frome. + stp x27, x28, [sp, #-16]! + stp x25, x26, [sp, #-16]! + stp x23, x24, [sp, #-16]! + stp x21, x22, [sp, #-16]! + stp x19, x20, [sp, #-16]! + stp x14, x15, [sp, #-16]! + stp x12, x13, [sp, #-16]! + stp x10, x11, [sp, #-16]! + stp x8, x9, [sp, #-16]! + stp x6, x7, [sp, #-16]! + stp x4, x5, [sp, #-16]! + stp x2, x3, [sp, #-16]! + stp x0, x1, [sp, #-16]! + stp q30, q31, [sp, #-32]! + stp q28, q29, [sp, #-32]! + stp q26, q27, [sp, #-32]! + stp q24, q25, [sp, #-32]! + stp q22, q23, [sp, #-32]! + stp q20, q21, [sp, #-32]! + stp q18, q19, [sp, #-32]! + stp q16, q17, [sp, #-32]! + stp q14, q15, [sp, #-32]! + stp q12, q13, [sp, #-32]! + stp q10, q11, [sp, #-32]! + stp q8, q9, [sp, #-32]! + stp q6, q7, [sp, #-32]! + stp q4, q5, [sp, #-32]! + stp q2, q3, [sp, #-32]! + stp q0, q1, [sp, #-32]! + + // Look up the return address and subtract 8 from it (on the assumption + // that it's a standard arm64 reentry trampoline) to get back the + // trampoline's address. + sub x0, x30, #8 + + // Call __orc_rt_resolve to look up the implementation corresponding to + // the calling stub, then store this in x17 (which we'll return to + // below). +#if !defined(__APPLE__) + bl __orc_rt_resolve +#else + bl ___orc_rt_resolve +#endif + mov x17, x0 + + // Restore the register state. + ldp q0, q1, [sp], #32 + ldp q2, q3, [sp], #32 + ldp q4, q5, [sp], #32 + ldp q6, q7, [sp], #32 + ldp q8, q9, [sp], #32 + ldp q10, q11, [sp], #32 + ldp q12, q13, [sp], #32 + ldp q14, q15, [sp], #32 + ldp q16, q17, [sp], #32 + ldp q18, q19, [sp], #32 + ldp q20, q21, [sp], #32 + ldp q22, q23, [sp], #32 + ldp q24, q25, [sp], #32 + ldp q26, q27, [sp], #32 + ldp q28, q29, [sp], #32 + ldp q30, q31, [sp], #32 + ldp x0, x1, [sp], #16 + ldp x2, x3, [sp], #16 + ldp x4, x5, [sp], #16 + ldp x6, x7, [sp], #16 + ldp x8, x9, [sp], #16 + ldp x10, x11, [sp], #16 + ldp x12, x13, [sp], #16 + ldp x14, x15, [sp], #16 + ldp x19, x20, [sp], #16 + ldp x21, x22, [sp], #16 + ldp x23, x24, [sp], #16 + ldp x25, x26, [sp], #16 + ldp x27, x28, [sp], #16 + ldp x29, x30, [sp], #16 + + // Return to the function implementation (rather than the stub). + ret x17 + +#endif // defined(__arm64__) || defined(__aarch64__) diff --git a/compiler-rt/lib/orc/sysv_reenter.x86-64.S b/compiler-rt/lib/orc/sysv_reenter.x86-64.S new file mode 100644 index 0000000000000..0a36280f1d1f8 --- /dev/null +++ b/compiler-rt/lib/orc/sysv_reenter.x86-64.S @@ -0,0 +1,81 @@ +//===-- orc_rt_macho_tlv.x86-64.s -------------------------------*- ASM -*-===// +// +// 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 is a part of the ORC runtime support library. +// +//===----------------------------------------------------------------------===// + +// The content of this file is x86_64-only +#if defined(__x86_64__) + +// Save all GRPS except %rsp. +// This value is also subtracted from %rsp below, despite the fact that %rbp +// has already been pushed, because we need %rsp to stay 16-byte aligned. +#define GPR_SAVE_SPACE_SIZE 15 * 8 +#define FXSAVE64_SAVE_SPACE_SIZE 512 +#define REGISTER_SAVE_SPACE_SIZE \ + GPR_SAVE_SPACE_SIZE + FXSAVE64_SAVE_SPACE_SIZE + + .text + + // returns address of TLV in %rax, all other registers preserved + .globl __orc_rt_sysv_reenter +__orc_rt_sysv_reenter: + pushq %rbp + movq %rsp, %rbp + subq $REGISTER_SAVE_SPACE_SIZE, %rsp + movq %rax, -8(%rbp) + movq %rbx, -16(%rbp) + movq %rcx, -24(%rbp) + movq %rdx, -32(%rbp) + movq %rsi, -40(%rbp) + movq %rdi, -48(%rbp) + movq %r8, -56(%rbp) + movq %r9, -64(%rbp) + movq %r10, -72(%rbp) + movq %r11, -80(%rbp) + movq %r12, -88(%rbp) + movq %r13, -96(%rbp) + movq %r14, -104(%rbp) + movq %r15, -112(%rbp) + fxsave64 (%rsp) + movq 8(%rbp), %rdi + + // Load return address and subtract five from it (on the assumption + // that it's a call instruction). + subq $5, %rdi + + // Call __orc_rt_resolve to look up the implementation corresponding to + // the calling stub, then store this in x17 (which we'll return to + // below). +#if !defined(__APPLE__) + call __orc_rt_resolve +#else + call ___orc_rt_resolve +#endif + movq %rax, 8(%rbp) + fxrstor64 (%rsp) + movq -112(%rbp), %r15 + movq -104(%rbp), %r14 + movq -96(%rbp), %r13 + movq -88(%rbp), %r12 + movq -80(%rbp), %r11 + movq -72(%rbp), %r10 + movq -64(%rbp), %r9 + movq -56(%rbp), %r8 + movq -48(%rbp), %rdi + movq -40(%rbp), %rsi + movq -32(%rbp), %rdx + movq -24(%rbp), %rcx + movq -16(%rbp), %rbx + movq -8(%rbp), %rax + addq $REGISTER_SAVE_SPACE_SIZE, %rsp + popq %rbp + ret + +#endif // defined(__x86_64__) diff --git a/compiler-rt/lib/orc/tests/unit/CMakeLists.txt b/compiler-rt/lib/orc/tests/unit/CMakeLists.txt index aec689a407be6..16cd16c45683d 100644 --- a/compiler-rt/lib/orc/tests/unit/CMakeLists.txt +++ b/compiler-rt/lib/orc/tests/unit/CMakeLists.txt @@ -2,6 +2,7 @@ set(UNITTEST_SOURCES adt_test.cpp bitmask_enum_test.cpp c_api_test.cpp + common.cpp endian_test.cpp error_test.cpp executor_address_test.cpp diff --git a/compiler-rt/lib/orc/tests/unit/common.cpp b/compiler-rt/lib/orc/tests/unit/common.cpp new file mode 100644 index 0000000000000..9479cc8094308 --- /dev/null +++ b/compiler-rt/lib/orc/tests/unit/common.cpp @@ -0,0 +1,6 @@ +#include + +/// Defined so that tests can use code that logs errors. +extern "C" void __orc_rt_log_error(const char *ErrMsg) { + fprintf(stderr, "orc runtime error: %s\n", ErrMsg); +} diff --git a/compiler-rt/lib/profile/InstrProfilingMerge.c b/compiler-rt/lib/profile/InstrProfilingMerge.c index 7cf1679811eb0..92721c4fd55ea 100644 --- a/compiler-rt/lib/profile/InstrProfilingMerge.c +++ b/compiler-rt/lib/profile/InstrProfilingMerge.c @@ -137,27 +137,23 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData, return 1; } - __llvm_profile_data *SrcDataStart, *SrcDataEnd, *SrcData, *DstData; __llvm_profile_header *Header = (__llvm_profile_header *)ProfileData; - char *SrcCountersStart, *DstCounter; - const char *SrcCountersEnd, *SrcCounter; - const char *SrcBitmapStart; - const char *SrcNameStart; - const char *SrcValueProfDataStart, *SrcValueProfData; uintptr_t CountersDelta = Header->CountersDelta; uintptr_t BitmapDelta = Header->BitmapDelta; - SrcDataStart = + __llvm_profile_data *SrcDataStart = (__llvm_profile_data *)(ProfileData + sizeof(__llvm_profile_header) + Header->BinaryIdsSize); - SrcDataEnd = SrcDataStart + Header->NumData; - SrcCountersStart = (char *)SrcDataEnd; - SrcCountersEnd = SrcCountersStart + - Header->NumCounters * __llvm_profile_counter_entry_size(); - SrcBitmapStart = SrcCountersEnd + __llvm_profile_get_num_padding_bytes( - SrcCountersEnd - SrcCountersStart); - SrcNameStart = SrcBitmapStart + Header->NumBitmapBytes; - SrcValueProfDataStart = + __llvm_profile_data *SrcDataEnd = SrcDataStart + Header->NumData; + uintptr_t SrcCountersStart = (uintptr_t)SrcDataEnd; + uintptr_t SrcCountersEnd = + SrcCountersStart + + Header->NumCounters * __llvm_profile_counter_entry_size(); + uintptr_t SrcBitmapStart = + SrcCountersEnd + + __llvm_profile_get_num_padding_bytes(SrcCountersEnd - SrcCountersStart); + uintptr_t SrcNameStart = SrcBitmapStart + Header->NumBitmapBytes; + uintptr_t SrcValueProfDataStart = SrcNameStart + getDistanceFromCounterToValueProf(Header); if (SrcNameStart < SrcCountersStart || SrcNameStart < SrcBitmapStart) return 1; @@ -165,13 +161,13 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData, // Merge counters by iterating the entire counter section when data section is // empty due to correlation. if (Header->NumData == 0) { - for (SrcCounter = SrcCountersStart, - DstCounter = __llvm_profile_begin_counters(); + for (uintptr_t SrcCounter = SrcCountersStart, + DstCounter = (uintptr_t)__llvm_profile_begin_counters(); SrcCounter < SrcCountersEnd;) { if (__llvm_profile_get_version() & VARIANT_MASK_BYTE_COVERAGE) { - *DstCounter &= *SrcCounter; + *(char *)DstCounter &= *(const char *)SrcCounter; } else { - *(uint64_t *)DstCounter += *(uint64_t *)SrcCounter; + *(uint64_t *)DstCounter += *(const uint64_t *)SrcCounter; } SrcCounter += __llvm_profile_counter_entry_size(); DstCounter += __llvm_profile_counter_entry_size(); @@ -179,6 +175,8 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData, return 0; } + __llvm_profile_data *SrcData, *DstData; + uintptr_t SrcValueProfData; for (SrcData = SrcDataStart, DstData = (__llvm_profile_data *)__llvm_profile_begin_data(), SrcValueProfData = SrcValueProfDataStart; @@ -187,10 +185,10 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData, // address of the data to the start address of the counter. On WIN64, // CounterPtr is a truncated 32-bit value due to COFF limitation. Sign // extend CounterPtr to get the original value. - char *DstCounters = - (char *)((uintptr_t)DstData + signextIfWin64(DstData->CounterPtr)); - char *DstBitmap = - (char *)((uintptr_t)DstData + signextIfWin64(DstData->BitmapPtr)); + uintptr_t DstCounters = + (uintptr_t)DstData + signextIfWin64(DstData->CounterPtr); + uintptr_t DstBitmap = + (uintptr_t)DstData + signextIfWin64(DstData->BitmapPtr); unsigned NVK = 0; // SrcData is a serialized representation of the memory image. We need to @@ -200,7 +198,7 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData, // CountersDelta computes the offset into the in-buffer counter section. // // On WIN64, CountersDelta is truncated as well, so no need for signext. - char *SrcCounters = + uintptr_t SrcCounters = SrcCountersStart + ((uintptr_t)SrcData->CounterPtr - CountersDelta); // CountersDelta needs to be decreased as we advance to the next data // record. @@ -214,13 +212,13 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData, for (unsigned I = 0; I < NC; I++) { if (__llvm_profile_get_version() & VARIANT_MASK_BYTE_COVERAGE) { // A value of zero signifies the function is covered. - DstCounters[I] &= SrcCounters[I]; + ((char *)DstCounters)[I] &= ((const char *)SrcCounters)[I]; } else { - ((uint64_t *)DstCounters)[I] += ((uint64_t *)SrcCounters)[I]; + ((uint64_t *)DstCounters)[I] += ((const uint64_t *)SrcCounters)[I]; } } - const char *SrcBitmap = + uintptr_t SrcBitmap = SrcBitmapStart + ((uintptr_t)SrcData->BitmapPtr - BitmapDelta); // BitmapDelta also needs to be decreased as we advance to the next data // record. @@ -232,7 +230,7 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData, return 1; // Merge Src and Dst Bitmap bytes by simply ORing them together. for (unsigned I = 0; I < NB; I++) - DstBitmap[I] |= SrcBitmap[I]; + ((char *)DstBitmap)[I] |= ((const char *)SrcBitmap)[I]; } /* Now merge value profile data. */ @@ -245,7 +243,7 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData, if (!NVK) continue; - if (SrcValueProfData >= ProfileData + ProfileSize) + if (SrcValueProfData >= (uintptr_t)ProfileData + ProfileSize) return 1; VPMergeHook((ValueProfData *)SrcValueProfData, DstData); SrcValueProfData = diff --git a/compiler-rt/lib/rtsan/rtsan.cpp b/compiler-rt/lib/rtsan/rtsan.cpp index 81cedb3b5114f..73340b34f6d4b 100644 --- a/compiler-rt/lib/rtsan/rtsan.cpp +++ b/compiler-rt/lib/rtsan/rtsan.cpp @@ -83,6 +83,9 @@ SANITIZER_INTERFACE_ATTRIBUTE void __rtsan_init() { SanitizerToolName = "RealtimeSanitizer"; InitializeFlags(); + + InitializePlatformEarly(); + InitializeInterceptors(); InitializeSuppressions(); diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index 4f7b534ee17a8..f000deb3039a8 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -46,6 +46,7 @@ void OSSpinLockLock(volatile OSSpinLock *__lock); #include #include #include +#include #include #include #include @@ -244,14 +245,29 @@ INTERCEPTOR(FILE *, fopen, const char *path, const char *mode) { return REAL(fopen)(path, mode); } +INTERCEPTOR(FILE *, freopen, const char *path, const char *mode, FILE *stream) { + __rtsan_notify_intercepted_call("freopen"); + return REAL(freopen)(path, mode, stream); +} + +// Streams + #if SANITIZER_INTERCEPT_FOPEN64 INTERCEPTOR(FILE *, fopen64, const char *path, const char *mode) { __rtsan_notify_intercepted_call("fopen64"); return REAL(fopen64)(path, mode); } -#define RTSAN_MAYBE_INTERCEPT_FOPEN64 INTERCEPT_FUNCTION(fopen64) + +INTERCEPTOR(FILE *, freopen64, const char *path, const char *mode, + FILE *stream) { + __rtsan_notify_intercepted_call("freopen64"); + return REAL(freopen64)(path, mode, stream); +} +#define RTSAN_MAYBE_INTERCEPT_FOPEN64 INTERCEPT_FUNCTION(fopen64); +#define RTSAN_MAYBE_INTERCEPT_FREOPEN64 INTERCEPT_FUNCTION(freopen64); #else #define RTSAN_MAYBE_INTERCEPT_FOPEN64 +#define RTSAN_MAYBE_INTERCEPT_FREOPEN64 #endif // SANITIZER_INTERCEPT_FOPEN64 INTERCEPTOR(size_t, fread, void *ptr, size_t size, size_t nitems, @@ -276,7 +292,11 @@ INTERCEPTOR(int, fputs, const char *s, FILE *stream) { return REAL(fputs)(s, stream); } -// Streams +INTERCEPTOR(FILE *, fdopen, int fd, const char *mode) { + __rtsan_notify_intercepted_call("fdopen"); + return REAL(fdopen)(fd, mode); +} + INTERCEPTOR(int, puts, const char *s) { __rtsan_notify_intercepted_call("puts"); return REAL(puts)(s); @@ -707,6 +727,17 @@ INTERCEPTOR(int, shutdown, int socket, int how) { return REAL(shutdown)(socket, how); } +#if SANITIZER_INTERCEPT_ACCEPT4 +INTERCEPTOR(int, accept4, int socket, struct sockaddr *address, + socklen_t *address_len, int flags) { + __rtsan_notify_intercepted_call("accept4"); + return REAL(accept4)(socket, address, address_len, flags); +} +#define RTSAN_MAYBE_INTERCEPT_ACCEPT4 INTERCEPT_FUNCTION(accept4) +#else +#define RTSAN_MAYBE_INTERCEPT_ACCEPT4 +#endif + // I/O Multiplexing INTERCEPTOR(int, poll, struct pollfd *fds, nfds_t nfds, int timeout) { @@ -893,6 +924,7 @@ void __rtsan::InitializeInterceptors() { INTERCEPT_FUNCTION(close); INTERCEPT_FUNCTION(fopen); RTSAN_MAYBE_INTERCEPT_FOPEN64; + RTSAN_MAYBE_INTERCEPT_FREOPEN64; INTERCEPT_FUNCTION(fread); INTERCEPT_FUNCTION(read); INTERCEPT_FUNCTION(write); @@ -910,6 +942,8 @@ void __rtsan::InitializeInterceptors() { RTSAN_MAYBE_INTERCEPT_CREAT64; INTERCEPT_FUNCTION(puts); INTERCEPT_FUNCTION(fputs); + INTERCEPT_FUNCTION(fdopen); + INTERCEPT_FUNCTION(freopen); INTERCEPT_FUNCTION(lseek); RTSAN_MAYBE_INTERCEPT_LSEEK64; INTERCEPT_FUNCTION(dup); @@ -956,6 +990,7 @@ void __rtsan::InitializeInterceptors() { INTERCEPT_FUNCTION(sendto); INTERCEPT_FUNCTION(shutdown); INTERCEPT_FUNCTION(socket); + RTSAN_MAYBE_INTERCEPT_ACCEPT4; RTSAN_MAYBE_INTERCEPT_SELECT; INTERCEPT_FUNCTION(pselect); diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp index 88df8ec46d0a3..b3fb32ee8dcd4 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp @@ -391,6 +391,26 @@ TEST_F(RtsanOpenedFileTest, IoctlBehavesWithOutputArg) { EXPECT_THAT(arg, Ge(0)); } +TEST_F(RtsanOpenedFileTest, FdopenDiesWhenRealtime) { + auto Func = [&]() { + FILE *f = fdopen(GetOpenFd(), "w"); + EXPECT_THAT(f, Ne(nullptr)); + }; + + ExpectRealtimeDeath(Func, "fdopen"); + ExpectNonRealtimeSurvival(Func); +} + +TEST_F(RtsanOpenedFileTest, FreopenDiesWhenRealtime) { + auto Func = [&]() { + FILE *newfile = freopen(GetTemporaryFilePath(), "w", GetOpenFile()); + EXPECT_THAT(newfile, Ne(nullptr)); + }; + + ExpectRealtimeDeath(Func, MAYBE_APPEND_64("freopen")); + ExpectNonRealtimeSurvival(Func); +} + TEST(TestRtsanInterceptors, IoctlBehavesWithOutputPointer) { // These initial checks just see if we CAN run these tests. // If we can't (can't open a socket, or can't find an interface, just @@ -860,6 +880,16 @@ TEST(TestRtsanInterceptors, AcceptingASocketDiesWhenRealtime) { ExpectNonRealtimeSurvival(Func); } +#if SANITIZER_INTERCEPT_ACCEPT4 +TEST(TestRtsanInterceptors, Accepting4ASocketDiesWhenRealtime) { + auto Func = []() { + EXPECT_LT(accept4(kNotASocketFd, nullptr, nullptr, 0), 0); + }; + ExpectRealtimeDeath(Func, "accept4"); + ExpectNonRealtimeSurvival(Func); +} +#endif + TEST(TestRtsanInterceptors, ConnectingASocketDiesWhenRealtime) { auto Func = []() { EXPECT_NE(connect(kNotASocketFd, nullptr, 0), 0); }; ExpectRealtimeDeath(Func, "connect"); diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_main.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_main.cpp index 50c726e09f287..ca560fc21035c 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_main.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_main.cpp @@ -19,7 +19,10 @@ extern "C" const char *__rtsan_default_options() { // and make sure we do not overwhelm the syslog while testing. Also, let's // turn symbolization off to speed up testing, especially when not running // with llvm-symbolizer but with atos. - return "symbolize=false:abort_on_error=0:log_to_syslog=0"; + return "symbolize=false:" + "abort_on_error=0:" + "log_to_syslog=0:" + "verify_interceptors=0:"; // some of our tests don't need interceptors #else // Let's turn symbolization off to speed up testing (more than 3 times speedup // observed). diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index ba3693dbd11f6..47436a6cd20f0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -347,7 +347,7 @@ extern const short *_tolower_tab_; uptr copy_length = internal_strnlen(s, size); \ char *new_mem = (char *)WRAP(malloc)(copy_length + 1); \ if (common_flags()->intercept_strndup) { \ - COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1)); \ + COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1)); \ } \ if (new_mem) { \ COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \ @@ -445,7 +445,7 @@ INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) { #endif #if SANITIZER_INTERCEPT_STRNDUP -INTERCEPTOR(char*, strndup, const char *s, uptr size) { +INTERCEPTOR(char*, strndup, const char *s, usize size) { void *ctx; COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size); } @@ -455,7 +455,7 @@ INTERCEPTOR(char*, strndup, const char *s, uptr size) { #endif // SANITIZER_INTERCEPT_STRNDUP #if SANITIZER_INTERCEPT___STRNDUP -INTERCEPTOR(char*, __strndup, const char *s, uptr size) { +INTERCEPTOR(char*, __strndup, const char *s, usize size) { void *ctx; COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size); } @@ -511,10 +511,10 @@ INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { } DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc, - const char *s1, const char *s2, uptr n, + const char *s1, const char *s2, usize n, int result) -INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { +INTERCEPTOR(int, strncmp, const char *s1, const char *s2, usize size) { if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) return internal_strncmp(s1, s2, size); void *ctx; @@ -576,7 +576,7 @@ INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { } DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr called_pc, - const char *s1, const char *s2, uptr size, + const char *s1, const char *s2, usize size, int result) INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T size) { @@ -833,13 +833,13 @@ INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) { #if SANITIZER_INTERCEPT_MEMCMP DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc, - const void *s1, const void *s2, uptr n, + const void *s1, const void *s2, usize n, int result) // Common code for `memcmp` and `bcmp`. int MemcmpInterceptorCommon(void *ctx, - int (*real_fn)(const void *, const void *, uptr), - const void *a1, const void *a2, uptr size) { + int (*real_fn)(const void *, const void *, usize), + const void *a1, const void *a2, usize size) { if (common_flags()->intercept_memcmp) { if (common_flags()->strict_memcmp) { // Check the entire regions even if the first bytes of the buffers are @@ -871,7 +871,7 @@ int MemcmpInterceptorCommon(void *ctx, return result; } -INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { +INTERCEPTOR(int, memcmp, const void *a1, const void *a2, usize size) { if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) return internal_memcmp(a1, a2, size); void *ctx; @@ -885,7 +885,7 @@ INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { #endif #if SANITIZER_INTERCEPT_BCMP -INTERCEPTOR(int, bcmp, const void *a1, const void *a2, uptr size) { +INTERCEPTOR(int, bcmp, const void *a1, const void *a2, usize size) { if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) return internal_memcmp(a1, a2, size); void *ctx; @@ -1138,7 +1138,7 @@ INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { #endif #if SANITIZER_INTERCEPT_FWRITE -INTERCEPTOR(SIZE_T, fwrite, const void *p, uptr size, uptr nmemb, void *file) { +INTERCEPTOR(SIZE_T, fwrite, const void *p, usize size, usize nmemb, void *file) { // libc file streams can call user-supplied functions, see fopencookie. void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, file); @@ -1313,7 +1313,7 @@ INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg5), sizeof(u64)); } else if (res != -1 && option == PR_GET_PDEATHSIG) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg2), sizeof(int)); -# if !SANITIZER_ANDROID +# if SANITIZER_GLIBC } else if (res != -1 && option == PR_SET_SECCOMP && arg2 == SECCOMP_MODE_FILTER) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg3), struct_sock_fprog_sz); @@ -6553,12 +6553,12 @@ static void MlockIsUnsupported() { SanitizerToolName); } -INTERCEPTOR(int, mlock, const void *addr, uptr len) { +INTERCEPTOR(int, mlock, const void *addr, usize len) { MlockIsUnsupported(); return 0; } -INTERCEPTOR(int, munlock, const void *addr, uptr len) { +INTERCEPTOR(int, munlock, const void *addr, usize len) { MlockIsUnsupported(); return 0; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc index 52e489d02cda8..1565a494140f6 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_memintrinsics.inc @@ -82,7 +82,7 @@ #endif #if SANITIZER_INTERCEPT_MEMSET -INTERCEPTOR(void *, memset, void *dst, int v, uptr size) { +INTERCEPTOR(void *, memset, void *dst, int v, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size); } @@ -93,7 +93,7 @@ INTERCEPTOR(void *, memset, void *dst, int v, uptr size) { #endif #if SANITIZER_INTERCEPT_MEMMOVE -INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) { +INTERCEPTOR(void *, memmove, void *dst, const void *src, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size); } @@ -104,7 +104,7 @@ INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) { #endif #if SANITIZER_INTERCEPT_MEMCPY -INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) { +INTERCEPTOR(void *, memcpy, void *dst, const void *src, usize size) { // On OS X, calling internal_memcpy here will cause memory corruptions, // because memcpy and memmove are actually aliases of the same // implementation. We need to use internal_memmove here. @@ -133,63 +133,63 @@ INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) { #endif #if SANITIZER_INTERCEPT_AEABI_MEM -INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) { +INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); } -INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) { +INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); } -INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) { +INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); } -INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) { +INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); } -INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) { +INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); } -INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) { +INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); } // Note the argument order. -INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) { +INTERCEPTOR(void *, __aeabi_memset, void *block, usize size, int c) { void *ctx; COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); } -INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) { +INTERCEPTOR(void *, __aeabi_memset4, void *block, usize size, int c) { void *ctx; COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); } -INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) { +INTERCEPTOR(void *, __aeabi_memset8, void *block, usize size, int c) { void *ctx; COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); } -INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) { +INTERCEPTOR(void *, __aeabi_memclr, void *block, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); } -INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) { +INTERCEPTOR(void *, __aeabi_memclr4, void *block, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); } -INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) { +INTERCEPTOR(void *, __aeabi_memclr8, void *block, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); } @@ -212,7 +212,7 @@ INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) { #endif // SANITIZER_INTERCEPT_AEABI_MEM #if SANITIZER_INTERCEPT___BZERO -INTERCEPTOR(void *, __bzero, void *block, uptr size) { +INTERCEPTOR(void *, __bzero, void *block, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); } @@ -222,7 +222,7 @@ INTERCEPTOR(void *, __bzero, void *block, uptr size) { #endif // SANITIZER_INTERCEPT___BZERO #if SANITIZER_INTERCEPT_BZERO -INTERCEPTOR(void *, bzero, void *block, uptr size) { +INTERCEPTOR(void *, bzero, void *block, usize size) { void *ctx; COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h index 9208b12552ff5..fff60c96f632f 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_internal_defs.h @@ -203,6 +203,12 @@ typedef __SIZE_TYPE__ usize; typedef uptr usize; #endif +#if defined(__s390__) && !defined(__s390x__) +typedef long ssize; +#else +typedef sptr ssize; +#endif + typedef u64 tid_t; // ----------- ATTENTION ------------- diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp index 26d2e8d4ed768..c8a0afccb254e 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_mac.cpp @@ -972,8 +972,9 @@ static const char kDyldInsertLibraries[] = "DYLD_INSERT_LIBRARIES"; LowLevelAllocator allocator_for_env; static bool ShouldCheckInterceptors() { - // Restrict "interceptors working?" check to ASan and TSan. - const char *sanitizer_names[] = {"AddressSanitizer", "ThreadSanitizer"}; + // Restrict "interceptors working?" check + const char *sanitizer_names[] = {"AddressSanitizer", "ThreadSanitizer", + "RealtimeSanitizer"}; size_t count = sizeof(sanitizer_names) / sizeof(sanitizer_names[0]); for (size_t i = 0; i < count; i++) { if (internal_strcmp(sanitizer_names[i], SanitizerToolName) == 0) diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 7d98f8e9a9d80..cacbb5b9959e0 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -313,7 +313,7 @@ extern unsigned struct_statvfs_sz; struct __sanitizer_iovec { void *iov_base; - uptr iov_len; + usize iov_len; }; #if !SANITIZER_ANDROID @@ -523,6 +523,7 @@ struct __sanitizer_dirent64 { unsigned short d_reclen; // more fields that we don't care about }; +extern unsigned struct_sock_fprog_sz; #endif #if defined(__x86_64__) && !defined(_LP64) @@ -1076,7 +1077,6 @@ extern unsigned struct_serial_struct_sz; extern unsigned struct_sockaddr_ax25_sz; extern unsigned struct_unimapdesc_sz; extern unsigned struct_unimapinit_sz; -extern unsigned struct_sock_fprog_sz; # endif // SANITIZER_LINUX && !SANITIZER_ANDROID extern const unsigned long __sanitizer_bufsiz; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp index ea513d5f263fe..fd0f989ee392b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -164,7 +164,24 @@ void UnmapOrDie(void *addr, uptr size, bool raw_report) { static void *ReturnNullptrOnOOMOrDie(uptr size, const char *mem_type, const char *mmap_type) { error_t last_error = GetLastError(); - if (last_error == ERROR_NOT_ENOUGH_MEMORY) + + // Assumption: VirtualAlloc is the last system call that was invoked before + // this method. + // VirtualAlloc emits one of 3 error codes when running out of memory + // 1. ERROR_NOT_ENOUGH_MEMORY: + // There's not enough memory to execute the command + // 2. ERROR_INVALID_PARAMETER: + // VirtualAlloc will return this if the request would allocate memory at an + // address exceeding or being very close to the maximum application address + // (the `lpMaximumApplicationAddress` field within the `SystemInfo` struct). + // This does not seem to be officially documented, but is corroborated here: + // https://stackoverflow.com/questions/45833674/why-does-virtualalloc-fail-for-lpaddress-greater-than-0x6ffffffffff + // 3. ERROR_COMMITMENT_LIMIT: + // VirtualAlloc will return this if e.g. the pagefile is too small to commit + // the requested amount of memory. + if (last_error == ERROR_NOT_ENOUGH_MEMORY || + last_error == ERROR_INVALID_PARAMETER || + last_error == ERROR_COMMITMENT_LIMIT) return nullptr; ReportMmapFailureAndDie(size, mem_type, mmap_type, last_error); } diff --git a/compiler-rt/lib/scudo/standalone/CMakeLists.txt b/compiler-rt/lib/scudo/standalone/CMakeLists.txt index dc700cec9becb..3f9ae866a7553 100644 --- a/compiler-rt/lib/scudo/standalone/CMakeLists.txt +++ b/compiler-rt/lib/scudo/standalone/CMakeLists.txt @@ -98,6 +98,7 @@ set(SCUDO_HEADERS tsd_exclusive.h tsd_shared.h tsd.h + type_traits.h vector.h wrappers_c_checks.h wrappers_c.h diff --git a/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h b/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h index 5477236ac1f39..ea12a5b1447f6 100644 --- a/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h +++ b/compiler-rt/lib/scudo/standalone/allocator_config_wrapper.h @@ -12,35 +12,7 @@ #include "condition_variable.h" #include "internal_defs.h" #include "secondary.h" - -namespace { - -template struct removeConst { - using type = T; -}; -template struct removeConst { - using type = T; -}; - -// This is only used for SFINAE when detecting if a type is defined. -template struct voidAdaptor { - using type = void; -}; - -// This is used for detecting the case that defines the flag with wrong type and -// it'll be viewed as undefined optional flag. -template struct assertSameType { - template struct isSame { - static constexpr bool value = false; - }; - template struct isSame { - static constexpr bool value = true; - }; - static_assert(isSame::value, "Flag type mismatches"); - using type = R; -}; - -} // namespace +#include "type_traits.h" namespace scudo { diff --git a/compiler-rt/lib/scudo/standalone/list.h b/compiler-rt/lib/scudo/standalone/list.h index c6bd32a8fa325..e0b82788251b7 100644 --- a/compiler-rt/lib/scudo/standalone/list.h +++ b/compiler-rt/lib/scudo/standalone/list.h @@ -10,17 +10,7 @@ #define SCUDO_LIST_H_ #include "internal_defs.h" - -// TODO: Move the helpers to a header. -namespace { -template struct isPointer { - static constexpr bool value = false; -}; - -template struct isPointer { - static constexpr bool value = true; -}; -} // namespace +#include "type_traits.h" namespace scudo { @@ -58,10 +48,11 @@ class LinkOp { template class LinkOp { public: - using LinkTy = decltype(T::Next); + using LinkTy = typename assertSameType< + typename removeConst::type, + typename removeConst::type>::type; LinkOp() = default; - // TODO: Check if the `BaseSize` can fit in `Size`. LinkOp(T *BaseT, uptr BaseSize) : Base(BaseT), Size(static_cast(BaseSize)) {} void init(T *LinkBase, uptr BaseSize) { @@ -80,11 +71,12 @@ template class LinkOp { } // Set `X->Next` to `Next`. void setNext(T *X, T *Next) const { - // TODO: Check if the offset fits in the size of `LinkTy`. - if (Next == nullptr) + if (Next == nullptr) { X->Next = getEndOfListVal(); - else + } else { + assertElementInRange(Next); X->Next = static_cast(Next - Base); + } } T *getPrev(T *X) const { @@ -96,17 +88,22 @@ template class LinkOp { } // Set `X->Prev` to `Prev`. void setPrev(T *X, T *Prev) const { - DCHECK_LT(reinterpret_cast(Prev), - reinterpret_cast(Base + Size)); - if (Prev == nullptr) + if (Prev == nullptr) { X->Prev = getEndOfListVal(); - else + } else { + assertElementInRange(Prev); X->Prev = static_cast(Prev - Base); + } } - // TODO: `LinkTy` should be the same as decltype(T::EndOfListVal). LinkTy getEndOfListVal() const { return T::EndOfListVal; } +private: + void assertElementInRange(T *X) const { + DCHECK_GE(reinterpret_cast(X), reinterpret_cast(Base)); + DCHECK_LE(static_cast(X - Base), Size); + } + protected: T *Base = nullptr; LinkTy Size = 0; diff --git a/compiler-rt/lib/scudo/standalone/type_traits.h b/compiler-rt/lib/scudo/standalone/type_traits.h new file mode 100644 index 0000000000000..16ed5a048f82b --- /dev/null +++ b/compiler-rt/lib/scudo/standalone/type_traits.h @@ -0,0 +1,47 @@ +//===-- type_traits.h -------------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef SCUDO_TYPE_TRAITS_H_ +#define SCUDO_TYPE_TRAITS_H_ + +namespace scudo { + +template struct removeConst { + using type = T; +}; +template struct removeConst { + using type = T; +}; + +// This is only used for SFINAE when detecting if a type is defined. +template struct voidAdaptor { + using type = void; +}; + +template struct assertSameType { + template struct isSame { + static constexpr bool value = false; + }; + template struct isSame { + static constexpr bool value = true; + }; + static_assert(isSame::value, "Type mismatches"); + using type = R; +}; + +template struct isPointer { + static constexpr bool value = false; +}; + +template struct isPointer { + static constexpr bool value = true; +}; + +} // namespace scudo + +#endif // SCUDO_TYPE_TRAITS_H_ diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp index 423d97e94d81a..f671c8167a3c4 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -97,7 +97,7 @@ extern "C" int pthread_key_create(unsigned *key, void (*destructor)(void* v)); extern "C" int pthread_setspecific(unsigned key, const void *v); DECLARE_REAL(int, pthread_mutexattr_gettype, void *, void *) DECLARE_REAL(int, fflush, __sanitizer_FILE *fp) -DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr size) +DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, usize size) DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr) extern "C" int pthread_equal(void *t1, void *t2); extern "C" void *pthread_self(); @@ -768,7 +768,7 @@ TSAN_INTERCEPTOR(char *, strcpy, char *dst, const char *src) { return REAL(strcpy)(dst, src); } -TSAN_INTERCEPTOR(char*, strncpy, char *dst, char *src, uptr n) { +TSAN_INTERCEPTOR(char*, strncpy, char *dst, char *src, usize n) { SCOPED_TSAN_INTERCEPTOR(strncpy, dst, src, n); uptr srclen = internal_strnlen(src, n); MemoryAccessRange(thr, pc, (uptr)dst, n, true); diff --git a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp index 53a3273e4e698..98662c5881c9f 100644 --- a/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp +++ b/compiler-rt/lib/ubsan_minimal/ubsan_minimal_handlers.cpp @@ -20,12 +20,42 @@ static __sanitizer::atomic_uintptr_t caller_pcs[kMaxCallerPcs]; // that "too many errors" has already been reported. static __sanitizer::atomic_uint32_t caller_pcs_sz; -__attribute__((noinline)) static bool report_this_error(uintptr_t caller) { +static char *append_str(const char *s, char *buf, const char *end) { + for (const char *p = s; (buf < end) && (*p != '\0'); ++p, ++buf) + *buf = *p; + return buf; +} + +static char *append_hex(uintptr_t d, char *buf, const char *end) { + // Print the address by nibbles. + for (unsigned shift = sizeof(uintptr_t) * 8; shift && buf < end;) { + shift -= 4; + unsigned nibble = (d >> shift) & 0xf; + *(buf++) = nibble < 10 ? nibble + '0' : nibble - 10 + 'a'; + } + return buf; +} + +static void format_msg(const char *kind, uintptr_t caller, char *buf, + const char *end) { + buf = append_str("ubsan: ", buf, end); + buf = append_str(kind, buf, end); + buf = append_str(" by 0x", buf, end); + buf = append_hex(caller, buf, end); + buf = append_str("\n", buf, end); + if (buf == end) + --buf; // Make sure we don't cause a buffer overflow. + *buf = '\0'; +} + +SANITIZER_INTERFACE_WEAK_DEF(void, __ubsan_report_error, const char *kind, + uintptr_t caller) { if (caller == 0) - return false; + return; while (true) { unsigned sz = __sanitizer::atomic_load_relaxed(&caller_pcs_sz); - if (sz > kMaxCallerPcs) return false; // early exit + if (sz > kMaxCallerPcs) + return; // early exit // when sz==kMaxCallerPcs print "too many errors", but only when cmpxchg // succeeds in order to not print it multiple times. if (sz > 0 && sz < kMaxCallerPcs) { @@ -33,7 +63,8 @@ __attribute__((noinline)) static bool report_this_error(uintptr_t caller) { for (unsigned i = 0; i < sz; ++i) { p = __sanitizer::atomic_load_relaxed(&caller_pcs[i]); if (p == 0) break; // Concurrent update. - if (p == caller) return false; + if (p == caller) + return; } if (p == 0) continue; // FIXME: yield? } @@ -44,34 +75,27 @@ __attribute__((noinline)) static bool report_this_error(uintptr_t caller) { if (sz == kMaxCallerPcs) { message("ubsan: too many errors\n"); - return false; + return; } __sanitizer::atomic_store_relaxed(&caller_pcs[sz], caller); - return true; - } -} -__attribute__((noinline)) static void decorate_msg(char *buf, - uintptr_t caller) { - // print the address by nibbles - for (unsigned shift = sizeof(uintptr_t) * 8; shift;) { - shift -= 4; - unsigned nibble = (caller >> shift) & 0xf; - *(buf++) = nibble < 10 ? nibble + '0' : nibble - 10 + 'a'; + char msg_buf[128]; + format_msg(kind, caller, msg_buf, msg_buf + sizeof(msg_buf)); + message(msg_buf); } - // finish the message - buf[0] = '\n'; - buf[1] = '\0'; } #if defined(__ANDROID__) extern "C" __attribute__((weak)) void android_set_abort_message(const char *); -static void abort_with_message(const char *msg) { - if (&android_set_abort_message) android_set_abort_message(msg); +static void abort_with_message(const char *kind, uintptr_t caller) { + char msg_buf[128]; + format_msg(kind, caller, msg_buf, msg_buf + sizeof(msg_buf)); + if (&android_set_abort_message) + android_set_abort_message(msg_buf); abort(); } #else -static void abort_with_message(const char *) { abort(); } +static void abort_with_message(const char *kind, uintptr_t caller) { abort(); } #endif #if SANITIZER_DEBUG @@ -89,33 +113,21 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) { #define INTERFACE extern "C" __attribute__((visibility("default"))) -// How many chars we need to reserve to print an address. -constexpr unsigned kAddrBuf = SANITIZER_WORDSIZE / 4; -#define MSG_TMPL(msg) "ubsan: " msg " by 0x" -#define MSG_TMPL_END(buf, msg) (buf + sizeof(MSG_TMPL(msg)) - 1) -// Reserve an additional byte for '\n'. -#define MSG_BUF_LEN(msg) (sizeof(MSG_TMPL(msg)) + kAddrBuf + 1) - -#define HANDLER_RECOVER(name, msg) \ - INTERFACE void __ubsan_handle_##name##_minimal() { \ - uintptr_t caller = GET_CALLER_PC(); \ - if (!report_this_error(caller)) return; \ - char msg_buf[MSG_BUF_LEN(msg)] = MSG_TMPL(msg); \ - decorate_msg(MSG_TMPL_END(msg_buf, msg), caller); \ - message(msg_buf); \ +#define HANDLER_RECOVER(name, kind) \ + INTERFACE void __ubsan_handle_##name##_minimal() { \ + __ubsan_report_error(kind, GET_CALLER_PC()); \ } -#define HANDLER_NORECOVER(name, msg) \ - INTERFACE void __ubsan_handle_##name##_minimal_abort() { \ - char msg_buf[MSG_BUF_LEN(msg)] = MSG_TMPL(msg); \ - decorate_msg(MSG_TMPL_END(msg_buf, msg), GET_CALLER_PC()); \ - message(msg_buf); \ - abort_with_message(msg_buf); \ +#define HANDLER_NORECOVER(name, kind) \ + INTERFACE void __ubsan_handle_##name##_minimal_abort() { \ + uintptr_t caller = GET_CALLER_PC(); \ + __ubsan_report_error(kind, caller); \ + abort_with_message(kind, caller); \ } -#define HANDLER(name, msg) \ - HANDLER_RECOVER(name, msg) \ - HANDLER_NORECOVER(name, msg) +#define HANDLER(name, kind) \ + HANDLER_RECOVER(name, kind) \ + HANDLER_NORECOVER(name, kind) HANDLER(type_mismatch, "type-mismatch") HANDLER(alignment_assumption, "alignment-assumption") diff --git a/compiler-rt/lib/xray/CMakeLists.txt b/compiler-rt/lib/xray/CMakeLists.txt index 7e3f1a0aa616e..e7f01a2f4f164 100644 --- a/compiler-rt/lib/xray/CMakeLists.txt +++ b/compiler-rt/lib/xray/CMakeLists.txt @@ -96,6 +96,16 @@ set(hexagon_SOURCES xray_trampoline_hexagon.S ) +set(riscv32_SOURCES + xray_riscv.cpp + xray_trampoline_riscv32.S + ) + +set(riscv64_SOURCES + xray_riscv.cpp + xray_trampoline_riscv64.S + ) + set(XRAY_SOURCE_ARCHS arm armhf @@ -156,6 +166,8 @@ set(XRAY_ALL_SOURCE_FILES ${mips64_SOURCES} ${mips64el_SOURCES} ${powerpc64le_SOURCES} + ${riscv32_SOURCES} + ${riscv64_SOURCES} ${XRAY_IMPL_HEADERS} ) list(REMOVE_DUPLICATES XRAY_ALL_SOURCE_FILES) diff --git a/compiler-rt/lib/xray/xray_interface.cpp b/compiler-rt/lib/xray/xray_interface.cpp index b6f0e6762f168..4ec492c266d80 100644 --- a/compiler-rt/lib/xray/xray_interface.cpp +++ b/compiler-rt/lib/xray/xray_interface.cpp @@ -57,6 +57,10 @@ static const int16_t cSledLength = 64; static const int16_t cSledLength = 8; #elif defined(__hexagon__) static const int16_t cSledLength = 20; +#elif defined(__riscv) && (__riscv_xlen == 64) +static const int16_t cSledLength = 68; +#elif defined(__riscv) && (__riscv_xlen == 32) +static const int16_t cSledLength = 52; #else #error "Unsupported CPU Architecture" #endif /* CPU architecture */ diff --git a/compiler-rt/lib/xray/xray_riscv.cpp b/compiler-rt/lib/xray/xray_riscv.cpp new file mode 100644 index 0000000000000..e3a7cdb18b640 --- /dev/null +++ b/compiler-rt/lib/xray/xray_riscv.cpp @@ -0,0 +1,266 @@ +//===-- xray_riscv.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 +// +//===----------------------------------------------------------------------===// +// +// This file is a part of XRay, a dynamic runtime instrumentation system. +// +// Implementation of RISC-V specific routines (32- and 64-bit). +// +//===----------------------------------------------------------------------===// +#include "sanitizer_common/sanitizer_common.h" +#include "xray_defs.h" +#include "xray_interface_internal.h" +#include + +namespace __xray { + +// The machine codes for some instructions used in runtime patching. +enum PatchOpcodes : uint32_t { + PO_ADDI = 0x00000013, // addi rd, rs1, imm + PO_ADD = 0x00000033, // add rd, rs1, rs2 + PO_SW = 0x00002023, // sw rs2, imm(rs1) + PO_SD = 0x00003023, // sd rs2, imm(rs1) + PO_LUI = 0x00000037, // lui rd, imm + PO_OR = 0x00006033, // or rd, rs1, rs2 + PO_SLLI = 0x00001013, // slli rd, rs1, shamt + PO_JALR = 0x00000067, // jalr rd, rs1 + PO_LW = 0x00002003, // lw rd, imm(rs1) + PO_LD = 0x00003003, // ld rd, imm(rs1) + PO_J = 0x0000006f, // jal imm + PO_NOP = PO_ADDI, // addi x0, x0, 0 +}; + +enum RegNum : uint32_t { + RN_X0 = 0, + RN_RA = 1, + RN_SP = 2, + RN_T1 = 6, + RN_A0 = 10, +}; + +static inline uint32_t encodeRTypeInstruction(uint32_t Opcode, uint32_t Rs1, + uint32_t Rs2, uint32_t Rd) { + return Rs2 << 20 | Rs1 << 15 | Rd << 7 | Opcode; +} + +static inline uint32_t encodeITypeInstruction(uint32_t Opcode, uint32_t Rs1, + uint32_t Rd, uint32_t Imm) { + return Imm << 20 | Rs1 << 15 | Rd << 7 | Opcode; +} + +static inline uint32_t encodeSTypeInstruction(uint32_t Opcode, uint32_t Rs1, + uint32_t Rs2, uint32_t Imm) { + uint32_t ImmMSB = (Imm & 0xfe0) << 20; + uint32_t ImmLSB = (Imm & 0x01f) << 7; + return ImmMSB | Rs2 << 20 | Rs1 << 15 | ImmLSB | Opcode; +} + +static inline uint32_t encodeUTypeInstruction(uint32_t Opcode, uint32_t Rd, + uint32_t Imm) { + return Imm << 12 | Rd << 7 | Opcode; +} + +static inline uint32_t encodeJTypeInstruction(uint32_t Opcode, uint32_t Rd, + uint32_t Imm) { + uint32_t ImmMSB = (Imm & 0x100000) << 11; + uint32_t ImmLSB = (Imm & 0x7fe) << 20; + uint32_t Imm11 = (Imm & 0x800) << 9; + uint32_t Imm1912 = (Imm & 0xff000); + return ImmMSB | ImmLSB | Imm11 | Imm1912 | Rd << 7 | Opcode; +} + +static uint32_t hi20(uint32_t val) { return (val + 0x800) >> 12; } +static uint32_t lo12(uint32_t val) { return val & 0xfff; } + +static inline bool patchSled(const bool Enable, const uint32_t FuncId, + const XRaySledEntry &Sled, + void (*TracingHook)()) XRAY_NEVER_INSTRUMENT { + // When |Enable| == true, + // We replace the following compile-time stub (sled): + // + // xray_sled_n: + // J .tmpN + // 21 or 33 C.NOPs (42 or 66 bytes) + // .tmpN + // + // With one of the following runtime patches: + // + // xray_sled_n (32-bit): + // addi sp, sp, -16 ;create stack frame + // sw ra, 12(sp) ;save return address + // sw a0, 8(sp) ;save register a0 + // lui ra, %hi(__xray_FunctionEntry/Exit) + // addi ra, ra, %lo(__xray_FunctionEntry/Exit) + // lui a0, %hi(function_id) + // addi a0, a0, %lo(function_id) ;pass function id + // jalr ra ;call Tracing hook + // lw a0, 8(sp) ;restore register a0 + // lw ra, 12(sp) ;restore return address + // addi sp, sp, 16 ;delete stack frame + // + // xray_sled_n (64-bit): + // addi sp, sp, -32 ;create stack frame + // sd ra, 24(sp) ;save return address + // sd a0, 16(sp) ;save register a0 + // sd t1, 8(sp) ;save register t1 + // lui t1, %highest(__xray_FunctionEntry/Exit) + // addi t1, t1, %higher(__xray_FunctionEntry/Exit) + // slli t1, t1, 32 + // lui ra, ra, %hi(__xray_FunctionEntry/Exit) + // addi ra, ra, %lo(__xray_FunctionEntry/Exit) + // add ra, t1, ra + // lui a0, %hi(function_id) + // addi a0, a0, %lo(function_id) ;pass function id + // jalr ra ;call Tracing hook + // ld t1, 8(sp) ;restore register t1 + // ld a0, 16(sp) ;restore register a0 + // ld ra, 24(sp) ;restore return address + // addi sp, sp, 32 ;delete stack frame + // + // Replacement of the first 4-byte instruction should be the last and atomic + // operation, so that the user code which reaches the sled concurrently + // either jumps over the whole sled, or executes the whole sled when the + // latter is ready. + // + // When |Enable|==false, we set back the first instruction in the sled to be + // J 44 bytes (rv32) + // J 68 bytes (rv64) + + uint32_t *Address = reinterpret_cast(Sled.address()); + if (Enable) { +#if __riscv_xlen == 64 + // If the ISA is RV64, the Tracing Hook needs to be typecast to a 64 bit + // value. + uint32_t LoTracingHookAddr = lo12(reinterpret_cast(TracingHook)); + uint32_t HiTracingHookAddr = hi20(reinterpret_cast(TracingHook)); + uint32_t HigherTracingHookAddr = + lo12((reinterpret_cast(TracingHook) + 0x80000000) >> 32); + uint32_t HighestTracingHookAddr = + hi20((reinterpret_cast(TracingHook) + 0x80000000) >> 32); +#elif __riscv_xlen == 32 + // We typecast the Tracing Hook to a 32 bit value for RV32 + uint32_t LoTracingHookAddr = lo12(reinterpret_cast(TracingHook)); + uint32_t HiTracingHookAddr = hi20((reinterpret_cast(TracingHook)); +#endif + uint32_t LoFunctionID = lo12(FuncId); + uint32_t HiFunctionID = hi20(FuncId); + + // The sled that is patched in for RISCV64 defined below. We need the entire + // sleds corresponding to both ISAs to be protected by defines because the + // first few instructions are all different, because we store doubles in + // case of RV64 and store words for RV32. Subsequently, we have LUI - and in + // case of RV64, we need extra instructions from this point on, so we see + // differences in addresses to which instructions are stored. + size_t Idx = 1U; + const uint32_t XLenBytes = __riscv_xlen / 8; +#if __riscv_xlen == 64 + const uint32_t LoadOp = PatchOpcodes::PO_LD; + const uint32_t StoreOp = PatchOpcodes::PO_SD; +#elif __riscv_xlen == 32 + const uint32_t LoadOp = PatchOpcodes::PO_LW; + const uint32_t StoreOp = PatchOpcodes::PO_SW; +#endif + + Address[Idx++] = encodeSTypeInstruction(StoreOp, RegNum::RN_SP, + RegNum::RN_RA, 3 * XLenBytes); + Address[Idx++] = encodeSTypeInstruction(StoreOp, RegNum::RN_SP, + RegNum::RN_A0, 2 * XLenBytes); + +#if __riscv_xlen == 64 + Address[Idx++] = encodeSTypeInstruction(StoreOp, RegNum::RN_SP, + RegNum::RN_T1, XLenBytes); + Address[Idx++] = encodeUTypeInstruction(PatchOpcodes::PO_LUI, RegNum::RN_T1, + HighestTracingHookAddr); + Address[Idx++] = + encodeITypeInstruction(PatchOpcodes::PO_ADDI, RegNum::RN_T1, + RegNum::RN_T1, HigherTracingHookAddr); + Address[Idx++] = encodeITypeInstruction(PatchOpcodes::PO_SLLI, + RegNum::RN_T1, RegNum::RN_T1, 32); +#endif + Address[Idx++] = encodeUTypeInstruction(PatchOpcodes::PO_LUI, RegNum::RN_RA, + HiTracingHookAddr); + Address[Idx++] = encodeITypeInstruction( + PatchOpcodes::PO_ADDI, RegNum::RN_RA, RegNum::RN_RA, LoTracingHookAddr); +#if __riscv_xlen == 64 + Address[Idx++] = encodeRTypeInstruction(PatchOpcodes::PO_ADD, RegNum::RN_RA, + RegNum::RN_T1, RegNum::RN_RA); +#endif + Address[Idx++] = encodeUTypeInstruction(PatchOpcodes::PO_LUI, RegNum::RN_A0, + HiFunctionID); + Address[Idx++] = encodeITypeInstruction( + PatchOpcodes::PO_ADDI, RegNum::RN_A0, RegNum::RN_A0, LoFunctionID); + Address[Idx++] = encodeITypeInstruction(PatchOpcodes::PO_JALR, + RegNum::RN_RA, RegNum::RN_RA, 0); + +#if __riscv_xlen == 64 + Address[Idx++] = + encodeITypeInstruction(LoadOp, RegNum::RN_SP, RegNum::RN_T1, XLenBytes); +#endif + Address[Idx++] = encodeITypeInstruction(LoadOp, RegNum::RN_SP, + RegNum::RN_A0, 2 * XLenBytes); + Address[Idx++] = encodeITypeInstruction(LoadOp, RegNum::RN_SP, + RegNum::RN_RA, 3 * XLenBytes); + Address[Idx++] = encodeITypeInstruction( + PatchOpcodes::PO_ADDI, RegNum::RN_SP, RegNum::RN_SP, 4 * XLenBytes); + + uint32_t CreateStackSpace = encodeITypeInstruction( + PatchOpcodes::PO_ADDI, RegNum::RN_SP, RegNum::RN_SP, -4 * XLenBytes); + + std::atomic_store_explicit( + reinterpret_cast *>(Address), CreateStackSpace, + std::memory_order_release); + } else { + uint32_t CreateBranch = encodeJTypeInstruction( + // Jump distance is different in both ISAs due to difference in size of + // sleds +#if __riscv_xlen == 64 + PatchOpcodes::PO_J, RegNum::RN_X0, + 68); // jump encodes an offset of 68 +#elif __riscv_xlen == 32 + PatchOpcodes::PO_J, RegNum::RN_X0, + 44); // jump encodes an offset of 44 +#endif + std::atomic_store_explicit( + reinterpret_cast *>(Address), CreateBranch, + std::memory_order_release); + } + return true; +} + +bool patchFunctionEntry(const bool Enable, const uint32_t FuncId, + const XRaySledEntry &Sled, + const XRayTrampolines &Trampolines, + bool LogArgs) XRAY_NEVER_INSTRUMENT { + // We don't support logging argument at this moment, so we always + // use EntryTrampoline. + return patchSled(Enable, FuncId, Sled, Trampolines.EntryTrampoline); +} + +bool patchFunctionExit( + const bool Enable, const uint32_t FuncId, const XRaySledEntry &Sled, + const XRayTrampolines &Trampolines) XRAY_NEVER_INSTRUMENT { + return patchSled(Enable, FuncId, Sled, Trampolines.ExitTrampoline); +} + +bool patchFunctionTailExit( + const bool Enable, const uint32_t FuncId, const XRaySledEntry &Sled, + const XRayTrampolines &Trampolines) XRAY_NEVER_INSTRUMENT { + return patchSled(Enable, FuncId, Sled, Trampolines.TailExitTrampoline); +} + +bool patchCustomEvent(const bool Enable, const uint32_t FuncId, + const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { + return false; +} + +bool patchTypedEvent(const bool Enable, const uint32_t FuncId, + const XRaySledEntry &Sled) XRAY_NEVER_INSTRUMENT { + return false; +} +} // namespace __xray + +extern "C" void __xray_ArgLoggerEntry() XRAY_NEVER_INSTRUMENT {} diff --git a/compiler-rt/lib/xray/xray_trampoline_riscv32.S b/compiler-rt/lib/xray/xray_trampoline_riscv32.S new file mode 100644 index 0000000000000..05e3d61e5ef71 --- /dev/null +++ b/compiler-rt/lib/xray/xray_trampoline_riscv32.S @@ -0,0 +1,89 @@ +//===-- xray_trampoline_riscv32.s ----------------------------------*- ASM -*-===// +// +// 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 is a part of XRay, a dynamic runtime instrumentation system. +// +// This implements the riscv32-specific assembler for the trampolines. +// +//===----------------------------------------------------------------------===// + +#include "../sanitizer_common/sanitizer_asm.h" + +.macro SAVE_ARG_REGISTERS + // Push argument registers to stack + addi sp, sp, -112 + CFI_DEF_CFA_OFFSET(112) + sw ra, 108(sp) + sw a7, 104(sp) + sw a6, 100(sp) + sw a5, 96(sp) + sw a4, 92(sp) + sw a3, 88(sp) + sw a2, 84(sp) + sw a1, 80(sp) + sw a0, 76(sp) + fsd fa7, 64(sp) + fsd fa6, 56(sp) + fsd fa5, 48(sp) + fsd fa4, 40(sp) + fsd fa3, 32(sp) + fsd fa2, 24(sp) + fsd fa1, 16(sp) + fsd fa0, 8(sp) +.endm + +.macro RESTORE_ARG_REGISTERS + // Restore argument registers + fld fa0, 8(sp) + fld fa1, 16(sp) + fld fa2, 24(sp) + fld fa3, 32(sp) + fld fa4, 40(sp) + fld fa5, 48(sp) + fld fa6, 56(sp) + fld fa7, 64(sp) + lw a0, 76(sp) + lw a1, 80(sp) + lw a2, 84(sp) + lw a3, 88(sp) + lw a4, 92(sp) + lw a5, 96(sp) + lw a6, 100(sp) + lw a7, 104(sp) + lw ra, 108(sp) + addi sp, sp, 112 + CFI_DEF_CFA_OFFSET(0) +.endm + +.macro SAVE_RET_REGISTERS + // Push return registers to stack + addi sp, sp, -32 + CFI_DEF_CFA_OFFSET(32) + sw ra, 28(sp) + sw a1, 24(sp) + sw a0, 20(sp) + fsd fa1, 8(sp) + fsd fa0, 0(sp) +.endm + +.macro RESTORE_RET_REGISTERS + // Restore return registers + fld fa0, 0(sp) + fld fa1, 8(sp) + lw a0, 20(sp) + lw a1, 24(sp) + lw ra, 28(sp) + addi sp, sp, 32 + CFI_DEF_CFA_OFFSET(0) +.endm + +.macro LOAD_XLEN, rd, src + lw \rd, \src +.endm + +#include "xray_trampoline_riscv_common.S" diff --git a/compiler-rt/lib/xray/xray_trampoline_riscv64.S b/compiler-rt/lib/xray/xray_trampoline_riscv64.S new file mode 100644 index 0000000000000..692350eaaa38e --- /dev/null +++ b/compiler-rt/lib/xray/xray_trampoline_riscv64.S @@ -0,0 +1,89 @@ +//===-- xray_trampoline_riscv64.s ----------------------------------*- ASM -*-===// +// +// 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 is a part of XRay, a dynamic runtime instrumentation system. +// +// This implements the riscv64-specific assembler for the trampolines. +// +//===----------------------------------------------------------------------===// + +#include "../sanitizer_common/sanitizer_asm.h" + +.macro SAVE_ARG_REGISTERS + // Push return registers to stack + addi sp, sp, -144 + CFI_DEF_CFA_OFFSET(144) + sd ra, 136(sp) + sd a7, 128(sp) + sd a6, 120(sp) + sd a5, 112(sp) + sd a4, 104(sp) + sd a3, 96(sp) + sd a2, 88(sp) + sd a1, 80(sp) + sd a0, 72(sp) + fsd fa7, 64(sp) + fsd fa6, 56(sp) + fsd fa5, 48(sp) + fsd fa4, 40(sp) + fsd fa3, 32(sp) + fsd fa2, 24(sp) + fsd fa1, 16(sp) + fsd fa0, 8(sp) +.endm + +.macro SAVE_RET_REGISTERS + // Push return registers to stack + addi sp, sp, -48 + CFI_DEF_CFA_OFFSET(48) + sd ra, 40(sp) + sd a1, 32(sp) + sd a0, 24(sp) + fsd fa1, 16(sp) + fsd fa0, 8(sp) +.endm + +.macro RESTORE_RET_REGISTERS + // Restore return registers + fld fa0, 8(sp) + fld fa1, 16(sp) + ld a0, 24(sp) + ld a1, 32(sp) + ld ra, 40(sp) + addi sp, sp, 48 + CFI_DEF_CFA_OFFSET(0) +.endm + +.macro RESTORE_ARG_REGISTERS + // Restore argument registers + fld fa0, 8(sp) + fld fa1, 16(sp) + fld fa2, 24(sp) + fld fa3, 32(sp) + fld fa4, 40(sp) + fld fa5, 48(sp) + fld fa6, 56(sp) + fld fa7, 64(sp) + ld a0, 72(sp) + ld a1, 80(sp) + ld a2, 88(sp) + ld a3, 96(sp) + ld a4, 104(sp) + ld a5, 112(sp) + ld a6, 120(sp) + ld a7, 128(sp) + ld ra, 136(sp) + addi sp, sp, 144 + CFI_DEF_CFA_OFFSET(0) +.endm + +.macro LOAD_XLEN, rd, src + ld \rd, \src +.endm + +#include "xray_trampoline_riscv_common.S" diff --git a/compiler-rt/lib/xray/xray_trampoline_riscv_common.S b/compiler-rt/lib/xray/xray_trampoline_riscv_common.S new file mode 100644 index 0000000000000..746d612e98204 --- /dev/null +++ b/compiler-rt/lib/xray/xray_trampoline_riscv_common.S @@ -0,0 +1,96 @@ +//===-- xray_trampoline_riscv_common.s --------------------------*- ASM -*-===// +// +// 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 is a part of XRay, a dynamic runtime instrumentation system. +// +// This implements the trampolines code shared between riscv32 and riscv64. +// +//===----------------------------------------------------------------------===// + +#include "../builtins/assembly.h" + + .text + .p2align 2 + .global ASM_SYMBOL(__xray_FunctionEntry) + ASM_TYPE_FUNCTION(__xray_FunctionEntry) +ASM_SYMBOL(__xray_FunctionEntry): + CFI_STARTPROC + SAVE_ARG_REGISTERS + + // Load the handler function pointer into a2 + la a2, ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE) + LOAD_XLEN a2, 0(a2) + + // Handler address will be null if it is not set + beq a2, x0, 1f + + // If we reach here, we are tracing an event + // a0 already contains function id + // a1 = 0 means we are tracing an entry event + li a1, 0 + jalr a2 + +1: + RESTORE_ARG_REGISTERS + jr ra + ASM_SIZE(__xray_FunctionEntry) + CFI_ENDPROC + + .text + .p2align 2 + .global ASM_SYMBOL(__xray_FunctionExit) + ASM_TYPE_FUNCTION(__xray_FunctionExit) +ASM_SYMBOL(__xray_FunctionExit): + CFI_STARTPROC + SAVE_RET_REGISTERS + + // Load the handler function pointer into a2 + la a2, ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE) + LOAD_XLEN a2, 0(a2) + + // Handler address will be null if it is not set + beq a2, x0, 1f + + // If we reach here, we are tracing an event + // a0 already contains function id + // a1 = 1 means we are tracing an exit event + li a1, 1 + jalr a2 + +1: + RESTORE_RET_REGISTERS + jr ra + ASM_SIZE(__xray_FunctionExit) + CFI_ENDPROC + + .text + .p2align 2 + .global ASM_SYMBOL(__xray_FunctionTailExit) + ASM_TYPE_FUNCTION(__xray_FunctionTailExit) +ASM_SYMBOL(__xray_FunctionTailExit): + CFI_STARTPROC + SAVE_ARG_REGISTERS + + // Load the handler function pointer into a2 + la a2, ASM_SYMBOL(_ZN6__xray19XRayPatchedFunctionE) + LOAD_XLEN a2, 0(a2) + + // Handler address will be null if it is not set + beq a2, x0, 1f + + // If we reach here, we are tracing an event + // a0 already contains function id + // a1 = 2 means we are tracing a tail exit event + li a1, 2 + jalr a2 + +1: + RESTORE_ARG_REGISTERS + jr ra + ASM_SIZE(__xray_FunctionTailExit) + CFI_ENDPROC diff --git a/compiler-rt/lib/xray/xray_tsc.h b/compiler-rt/lib/xray/xray_tsc.h index e1cafe1bf11d2..b62a686d6ce0f 100644 --- a/compiler-rt/lib/xray/xray_tsc.h +++ b/compiler-rt/lib/xray/xray_tsc.h @@ -43,7 +43,7 @@ inline uint64_t getTSCFrequency() XRAY_NEVER_INSTRUMENT { #elif defined(__powerpc64__) #include "xray_powerpc64.inc" #elif defined(__arm__) || defined(__aarch64__) || defined(__mips__) || \ - defined(__hexagon__) || defined(__loongarch_lp64) + defined(__hexagon__) || defined(__loongarch_lp64) || defined(__riscv) // Emulated TSC. // There is no instruction like RDTSCP in user mode on ARM. ARM's CP15 does // not have a constant frequency like TSC on x86(_64), it may go faster diff --git a/compiler-rt/test/asan/TestCases/Linux/global-overflow-bfd.cpp b/compiler-rt/test/asan/TestCases/Linux/global-overflow-bfd.cpp index bf82a517df37e..67331606c3ba0 100644 --- a/compiler-rt/test/asan/TestCases/Linux/global-overflow-bfd.cpp +++ b/compiler-rt/test/asan/TestCases/Linux/global-overflow-bfd.cpp @@ -2,6 +2,9 @@ // false negatives with the BFD linker. // RUN: %clangxx_asan -fuse-ld=bfd -Wl,-gc-sections -ffunction-sections -fdata-sections -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s +// Android does not use bfd. +// UNSUPPORTED: android + #include int main(int argc, char **argv) { static char XXX[10]; diff --git a/compiler-rt/test/asan/TestCases/Windows/allocator_may_return_null_limits.cpp b/compiler-rt/test/asan/TestCases/Windows/allocator_may_return_null_limits.cpp new file mode 100644 index 0000000000000..90db0d45af2d7 --- /dev/null +++ b/compiler-rt/test/asan/TestCases/Windows/allocator_may_return_null_limits.cpp @@ -0,0 +1,34 @@ +// RUN: %clangxx_asan -O0 %s -o %t +// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-ABORT +// RUN: %env_asan_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RETURN-NULL + +// RUN: %clangxx_asan -O0 %s -o %t -DUSER_FUNCTION +// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RETURN-NULL + +#if USER_FUNCTION +// On Windows, flags configured through the user-defined function `__asan_default_options` +// are suspected to not always be honored according to GitHub bug: +// https://github.com/llvm/llvm-project/issues/117925 +// This test ensures we do not regress on `allocator_may_return_null` specifically. +extern "C" __declspec(dllexport) extern const char *__asan_default_options() { + return "allocator_may_return_null=1"; +} +#endif + +#include +#include +#include +#include + +int main() { + // Attempt to allocate an excessive amount of memory, which should + // terminate the program unless `allocator_may_return_null` is set. + size_t max = std::numeric_limits::max(); + + // CHECK-ABORT: exceeds maximum supported size + // CHECK-ABORT: ABORT + free(malloc(max)); + + printf("Success"); // CHECK-RETURN-NULL: Success + return 0; +} diff --git a/compiler-rt/test/memprof/TestCases/default_options.cpp b/compiler-rt/test/memprof/TestCases/default_options.cpp index 1b6b61fc048b6..4042a7df588b0 100644 --- a/compiler-rt/test/memprof/TestCases/default_options.cpp +++ b/compiler-rt/test/memprof/TestCases/default_options.cpp @@ -1,5 +1,8 @@ // RUN: %clangxx_memprof -O2 %s -o %t && %run %t 2>&1 | FileCheck %s +// Check that overriding __memprof_default_options() takes precedence over the LLVM flag +// RUN: %clangxx_memprof -O2 %s -o %t-flag -mllvm -memprof-runtime-default-options="verbosity=0 help=0" && %run %t-flag 2>&1 | FileCheck %s + const char *kMemProfDefaultOptions = "verbosity=1 help=1"; extern "C" const char *__memprof_default_options() { diff --git a/compiler-rt/test/memprof/TestCases/dump_at_exit.cpp b/compiler-rt/test/memprof/TestCases/dump_at_exit.cpp new file mode 100644 index 0000000000000..426849d1cea01 --- /dev/null +++ b/compiler-rt/test/memprof/TestCases/dump_at_exit.cpp @@ -0,0 +1,16 @@ +// RUN: %clangxx_memprof %s -o %t + +// RUN: %env_memprof_opts=print_text=true:log_path=stdout:dump_at_exit=false %run %t | count 0 +// RUN: %env_memprof_opts=print_text=true:log_path=stdout:dump_at_exit=true %run %t | FileCheck %s + +#include +#include + +int main() { + char *x = (char *)malloc(10); + memset(x, 0, 10); + free(x); + return 0; +} + +// CHECK: Recorded MIBs diff --git a/compiler-rt/test/memprof/TestCases/set_options.cpp b/compiler-rt/test/memprof/TestCases/set_options.cpp new file mode 100644 index 0000000000000..dddcfcf98c5c0 --- /dev/null +++ b/compiler-rt/test/memprof/TestCases/set_options.cpp @@ -0,0 +1,16 @@ +// RUN: %clangxx_memprof %s -o %t-default +// RUN: %run %t-default | FileCheck %s --check-prefix=DEFAULT + +// RUN: %clangxx_memprof %s -mllvm -memprof-runtime-default-options="print_text=true,log_path=stdout,atexit=false" -o %t +// RUN: %run %t | FileCheck %s + +#include +#include + +int main() { + printf("Options: \"%s\"\n", __memprof_default_options()); + return 0; +} + +// DEFAULT: Options: "" +// CHECK: Options: "print_text=true,log_path=stdout,atexit=false" diff --git a/llvm/test/ExecutionEngine/JITLink/Generic/Inputs/foo-ret-42.ll b/compiler-rt/test/orc/TestCases/Generic/Inputs/foo-ret-42.ll similarity index 100% rename from llvm/test/ExecutionEngine/JITLink/Generic/Inputs/foo-ret-42.ll rename to compiler-rt/test/orc/TestCases/Generic/Inputs/foo-ret-42.ll diff --git a/llvm/test/ExecutionEngine/JITLink/Generic/Inputs/var-x-42.ll b/compiler-rt/test/orc/TestCases/Generic/Inputs/var-x-42.ll similarity index 100% rename from llvm/test/ExecutionEngine/JITLink/Generic/Inputs/var-x-42.ll rename to compiler-rt/test/orc/TestCases/Generic/Inputs/var-x-42.ll diff --git a/llvm/test/ExecutionEngine/JITLink/Generic/lazy-link.ll b/compiler-rt/test/orc/TestCases/Generic/lazy-link.ll similarity index 70% rename from llvm/test/ExecutionEngine/JITLink/Generic/lazy-link.ll rename to compiler-rt/test/orc/TestCases/Generic/lazy-link.ll index 72325e198721b..5a8dbfc532b0f 100644 --- a/llvm/test/ExecutionEngine/JITLink/Generic/lazy-link.ll +++ b/compiler-rt/test/orc/TestCases/Generic/lazy-link.ll @@ -4,13 +4,14 @@ ; referenced by main, should be linked (despite being passed with -lazy). ; ; RUN: rm -rf %t && mkdir -p %t -; RUN: llc -filetype=obj -o %t/foo.o %S/Inputs/foo-ret-42.ll -; RUN: llc -filetype=obj -o %t/x.o %S/Inputs/var-x-42.ll -; RUN: llc -filetype=obj -o %t/main.o %s -; RUN: llvm-jitlink -noexec -show-linked-files %t/main.o -lazy %t/foo.o \ +; RUN: %clang -c -o %t/foo.o %S/Inputs/foo-ret-42.ll +; RUN: %clang -c -o %t/x.o %S/Inputs/var-x-42.ll +; RUN: %clang -c -o %t/main.o %s +; RUN: %llvm_jitlink -noexec -show-linked-files %t/main.o -lazy %t/foo.o \ ; RUN: -lazy %t/x.o | FileCheck %s ; -; UNSUPPORTED: system-windows, target={{arm[^6][^4].*}}, target=powerpc64{{.*}} +; UNSUPPORTED: system-windows +; REQUIRES: target={{(arm|aarch|x86_)64.*}} ; ; CHECK: Linking {{.*}}main.o ; CHECK-DAG: Linking diff --git a/compiler-rt/test/orc/TestCases/Generic/orc-rt-executor-usage.test b/compiler-rt/test/orc/TestCases/Generic/orc-rt-executor-usage.test deleted file mode 100644 index 951688d7961d4..0000000000000 --- a/compiler-rt/test/orc/TestCases/Generic/orc-rt-executor-usage.test +++ /dev/null @@ -1,6 +0,0 @@ -// Test that the orc-remote-executor tool errors out as expected when called -// with no arguments. -// -// RUN: not %orc_rt_executor 2>&1 | FileCheck %s - -// CHECK: usage: orc-rt-executor [help] [] ... diff --git a/compiler-rt/test/orc/lit.cfg.py b/compiler-rt/test/orc/lit.cfg.py index 6dfa94b11cc9d..7a6eb4e7de325 100644 --- a/compiler-rt/test/orc/lit.cfg.py +++ b/compiler-rt/test/orc/lit.cfg.py @@ -16,6 +16,11 @@ host_arch_compatible = True if host_arch_compatible: config.available_features.add("host-arch-compatible") + +# If the target OS hasn't been set then assume host. +if not config.target_os: + config.target_os = config.host_os + config.test_target_is_host_executable = ( config.target_os == config.host_os and host_arch_compatible ) diff --git a/compiler-rt/test/rtsan/Darwin/dlopen.cpp b/compiler-rt/test/rtsan/Darwin/dlopen.cpp new file mode 100644 index 0000000000000..1aabe5cb6e580 --- /dev/null +++ b/compiler-rt/test/rtsan/Darwin/dlopen.cpp @@ -0,0 +1,44 @@ +// Checks that on OS X 10.11+ dlopen'ing a RTsanified library from a +// non-instrumented program exits with a user-friendly message. + +// REQUIRES: osx-autointerception + +// XFAIL: ios + +// RUN: %clangxx -fsanitize=realtime %s -o %t.so -shared -DSHARED_LIB +// RUN: %clangxx %s -o %t + +// RUN: RTSAN_DYLIB_PATH=`%clangxx -fsanitize=realtime %s -### 2>&1 \ +// RUN: | grep "libclang_rt.rtsan_osx_dynamic.dylib" \ +// RUN: | sed -e 's/.*"\(.*libclang_rt.rtsan_osx_dynamic.dylib\)".*/\1/'` + +// Launching a non-instrumented binary that dlopen's an instrumented library should fail. +// RUN: not %run %t %t.so 2>&1 | FileCheck %s --check-prefix=CHECK-FAIL +// Launching a non-instrumented binary with an explicit DYLD_INSERT_LIBRARIES should work. +// RUN: DYLD_INSERT_LIBRARIES=$RTSAN_DYLIB_PATH %run %t %t.so 2>&1 | FileCheck %s + +// Launching an instrumented binary with the DYLD_INSERT_LIBRARIES env variable has no error +// RUN: %clangxx -fsanitize=realtime %s -o %t +// RUN: DYLD_INSERT_LIBRARIES=$RTSAN_DYLIB_PATH %run %t %t.so 2>&1 | FileCheck %s --check-prefix=CHECK-INSTRUMENTED + +#include +#include + +#if defined(SHARED_LIB) +extern "C" void foo() { fprintf(stderr, "Hello world.\n"); } +#else // defined(SHARED_LIB) +int main(int argc, char *argv[]) { + void *handle = dlopen(argv[1], RTLD_NOW); + void (*foo)() = (void (*)())dlsym(handle, "foo"); + foo(); +} +#endif // defined(SHARED_LIB) + +// CHECK: Hello world. +// CHECK-NOT: ERROR: Interceptors are not working. + +// CHECK-FAIL-NOT: Hello world. +// CHECK-FAIL: ERROR: Interceptors are not working. + +// CHECK-INSTRUMENTED-NOT: ERROR: Interceptors are not working +// CHECK-INSTRUMENTED: Hello world. diff --git a/compiler-rt/test/ubsan_minimal/TestCases/override-callback.c b/compiler-rt/test/ubsan_minimal/TestCases/override-callback.c new file mode 100644 index 0000000000000..e11a3712f1be3 --- /dev/null +++ b/compiler-rt/test/ubsan_minimal/TestCases/override-callback.c @@ -0,0 +1,15 @@ +// RUN: %clang -fsanitize=implicit-integer-sign-change %s -o %t && %run %t 0 2>&1 | FileCheck %s +#include +#include +#include + +static int Result; + +void __ubsan_report_error(const char *kind, uintptr_t caller) { + fprintf(stderr, "CUSTOM_CALLBACK: %s\n", kind); +} + +int main(int argc, const char **argv) { + int32_t t0 = (~((uint32_t)0)); + // CHECK: CUSTOM_CALLBACK: implicit-conversion +} diff --git a/flang/Maintainers.md b/flang/Maintainers.md new file mode 100644 index 0000000000000..f4a7635389138 --- /dev/null +++ b/flang/Maintainers.md @@ -0,0 +1,95 @@ +# Flang maintainers + +This file is a list of the +[maintainers](https://llvm.org/docs/DeveloperPolicy.html#maintainers) for +Flang + +## Active maintainers + +### Lead maintainers +The following people are the active maintainers for the project. Please reach +out to them for code reviews, questions about their area of expertise, or other +assistance. + +#### All areas not covered by others +Steve Scalpone \ +sscalpone@nvidia.com (email), sscalpone (GitHub), sscalpone (Discourse) + +#### Backend (Lowering, Fortran dialects, Codegen) +Jean Perier \ +jperier@nvidia.com (email), jeanPerier (GitHub), jeanPerier (Discourse) + +### Component maintainers +These maintainers are responsible for particular high-level components within +Flang that are typically contained to one area of the compiler. + +#### Driver +Andrzej Warzyński \ +andrzej.warzynski@arm.com (email), banach-space (GitHub), banach-space (Discourse) + +Tarun Prabhu \ +tarun@lanl.gov (email), tarunprabhu (GitHub), tarunprabhu (Discourse) + +#### Alias Analysis +Renaud Kauffmann \ +rkauffmann@nvidia.com (email), Renaud-K (GitHub), Renaud-K (Discourse) + +#### PFT, Block, IEEE support +Val Donaldson \ +vdonaldson@nvidia.com (email), vdonaldson (GitHub) + +#### Lowering, HLFIR, FIR, Codegen +Jean Perier \ +jperier@nvidia.com (email), jeanPerier (GitHub), jeanPerier (Discourse) + +Slava Zakharin \ +szakharin@nvidia.com (email), vzakhari (GitHub), szakharin (Discourse) + +Tom Eccles \ +tom.eccles@arm.com (email), tblah (GitHub), tblah (Discourse) + +Valentin Clement \ +clementval@gmail.com (email), clementval (GitHub), clementval (Discourse) + +#### OpenMP +##### CPU support +Tom Eccles \ +tom.eccles@arm.com (email), tblah (GitHub), tblah (Discourse) + +##### OpenMP 6.0 +Krzysztof Parzyszek \ +Krzysztof.Parzyszek@amd.com (email), kparzysz (GitHub), kparzysz (Discourse) + +##### Target Offload +Sergio Afonso \ +safonsof@amd.com (email), skatrak (GitHub), skatrak (Discourse) + +#### OpenACC +Valentin Clement \ +clementval@gmail.com (email), clementval (GitHub), clementval (Discourse) + +Razvan Lupusoru \ +razvan.lupusoru@gmail.com (email), razvanlupusoru (GitHub), razvan.lupusoru (Discourse) + +#### CUDA Fortran +Valentin Clement \ +clementval@gmail.com (email), clementval (GitHub), clementval (Discourse) + +#### Debug +Abid Qadeer \ +haqadeer@amd.com (email), abidh (GitHub), abidh (Discourse) + +## Inactive Maintainers +### Lead Maintainers +#### Backend : (Lowering, FIR, Codegen) +Eric Schweitz \ +eschweitz@nvidia.com (email), schweitzpgi (GitHub), schweitz (Discourse) + +### Component Maintainers +#### Semantics +Tim Keith + +#### OpenMP +Kiran Chandramohan \ +kiran.chandramohan@arm.com (email), kiranchandramohan (GitHub), kiranchandramohan (Discourse) + diff --git a/flang/Maintainers.txt b/flang/Maintainers.txt deleted file mode 100644 index a8e2fe07a9853..0000000000000 --- a/flang/Maintainers.txt +++ /dev/null @@ -1,18 +0,0 @@ -This file is a list of the people responsible for ensuring that patches for a -particular part of Flang are reviewed, either by themself or by someone else. -They are also the gatekeepers for their part of Flang, with the final word on -what goes in or not. - -The list is sorted by surname and formatted to allow easy grepping and -beautification by scripts. The fields are: name (N), email (E), web-address -(W), PGP key ID and fingerprint (P), description (D), snail-mail address -(S) and (I) IRC handle. Each entry should contain at least the (N), (E) and -(D) fields. - -N: Steve Scalpone -E: sscalpone@nvidia.com -D: Anything not covered by others - -N: Andrzej Warzynski -E: andrzej.warzynski@arm.com -D: Driver diff --git a/flang/docs/Intrinsics.md b/flang/docs/Intrinsics.md index 94bca7a3972b6..d0b7999fbd067 100644 --- a/flang/docs/Intrinsics.md +++ b/flang/docs/Intrinsics.md @@ -705,6 +705,7 @@ MALLOC, FREE ### Library subroutine ``` +CALL BACKTRACE() CALL FDATE(TIME) CALL GETLOG(USRNAME) CALL GETENV(NAME [, VALUE, LENGTH, STATUS, TRIM_NAME, ERRMSG ]) @@ -769,7 +770,7 @@ This phase currently supports all the intrinsic procedures listed above but the | Intrinsic subroutines |MVBITS (elemental), CPU_TIME, DATE_AND_TIME, EVENT_QUERY, EXECUTE_COMMAND_LINE, GET_COMMAND, GET_COMMAND_ARGUMENT, GET_ENVIRONMENT_VARIABLE, MOVE_ALLOC, RANDOM_INIT, RANDOM_NUMBER, RANDOM_SEED, SIGNAL, SLEEP, SYSTEM, SYSTEM_CLOCK | | Atomic intrinsic subroutines | ATOMIC_ADD | | Collective intrinsic subroutines | CO_REDUCE | -| Library subroutines | FDATE, GETLOG, GETENV | +| Library subroutines | BACKTRACE, FDATE, GETLOG, GETENV | ### Intrinsic Function Folding diff --git a/flang/examples/FeatureList/FeatureList.cpp b/flang/examples/FeatureList/FeatureList.cpp index 41a6255207976..3a689c335c81c 100644 --- a/flang/examples/FeatureList/FeatureList.cpp +++ b/flang/examples/FeatureList/FeatureList.cpp @@ -495,8 +495,7 @@ struct NodeVisitor { READ_FEATURE(OmpIfClause::Modifier) READ_FEATURE(OmpDirectiveNameModifier) READ_FEATURE(OmpLinearClause) - READ_FEATURE(OmpLinearClause::WithModifier) - READ_FEATURE(OmpLinearClause::WithoutModifier) + READ_FEATURE(OmpLinearClause::Modifier) READ_FEATURE(OmpLinearModifier) READ_FEATURE(OmpLinearModifier::Value) READ_FEATURE(OmpLoopDirective) diff --git a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp index 2dc480f0c901b..665b92be00898 100644 --- a/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp +++ b/flang/examples/FlangOmpReport/FlangOmpReportVisitor.cpp @@ -143,6 +143,10 @@ std::string OpenMPCounterVisitor::getName(const OpenMPConstruct &c) { }, c.u); }, + [&](const OpenMPErrorConstruct &c) -> std::string { + const CharBlock &source{std::get<0>(c.t).source}; + return normalize_construct_name(source.ToString()); + }, [&](const OpenMPSectionConstruct &c) -> std::string { return "section"; }, diff --git a/flang/include/flang/Common/Fortran-consts.h b/flang/include/flang/Common/Fortran-consts.h index eedcdae335c40..cf7884e7454c0 100644 --- a/flang/include/flang/Common/Fortran-consts.h +++ b/flang/include/flang/Common/Fortran-consts.h @@ -9,7 +9,7 @@ #ifndef FORTRAN_COMMON_FORTRAN_CONSTS_H_ #define FORTRAN_COMMON_FORTRAN_CONSTS_H_ -#include "flang/Common/enum-class.h" +#include "enum-set.h" #include namespace Fortran::common { diff --git a/flang/include/flang/Lower/AbstractConverter.h b/flang/include/flang/Lower/AbstractConverter.h index 583fa6fb215a7..307ba6a918777 100644 --- a/flang/include/flang/Lower/AbstractConverter.h +++ b/flang/include/flang/Lower/AbstractConverter.h @@ -118,8 +118,11 @@ class AbstractConverter { /// For a given symbol which is host-associated, create a clone using /// parameters from the host-associated symbol. + /// The clone is default initialized if its type has any default + /// initialization unless `skipDefaultInit` is set. virtual bool - createHostAssociateVarClone(const Fortran::semantics::Symbol &sym) = 0; + createHostAssociateVarClone(const Fortran::semantics::Symbol &sym, + bool skipDefaultInit) = 0; virtual void createHostAssociateVarCloneDealloc(const Fortran::semantics::Symbol &sym) = 0; diff --git a/flang/include/flang/Lower/Allocatable.h b/flang/include/flang/Lower/Allocatable.h index 1209b157ed1f4..0e89af94af40f 100644 --- a/flang/include/flang/Lower/Allocatable.h +++ b/flang/include/flang/Lower/Allocatable.h @@ -15,7 +15,7 @@ #include "flang/Lower/AbstractConverter.h" #include "flang/Optimizer/Builder/MutableBox.h" -#include "flang/Runtime/allocator-registry.h" +#include "flang/Runtime/allocator-registry-consts.h" #include "llvm/ADT/StringRef.h" namespace mlir { diff --git a/flang/include/flang/Lower/LoweringOptions.def b/flang/include/flang/Lower/LoweringOptions.def index 231de533fbd30..0b22e54b648e9 100644 --- a/flang/include/flang/Lower/LoweringOptions.def +++ b/flang/include/flang/Lower/LoweringOptions.def @@ -38,10 +38,5 @@ ENUM_LOWERINGOPT(Underscoring, unsigned, 1, 1) /// (i.e. wraps around as two's complement). Off by default. ENUM_LOWERINGOPT(IntegerWrapAround, unsigned, 1, 0) -/// If true, add nsw flags to loop variable increments. -/// Off by default. -/// TODO: integrate this option with the above -ENUM_LOWERINGOPT(NSWOnLoopVarInc, unsigned, 1, 0) - #undef LOWERINGOPT #undef ENUM_LOWERINGOPT diff --git a/flang/include/flang/Optimizer/Builder/HLFIRTools.h b/flang/include/flang/Optimizer/Builder/HLFIRTools.h index efbd9e4f50d43..c8aad644bc784 100644 --- a/flang/include/flang/Optimizer/Builder/HLFIRTools.h +++ b/flang/include/flang/Optimizer/Builder/HLFIRTools.h @@ -366,6 +366,10 @@ struct LoopNest { /// Generate a fir.do_loop nest looping from 1 to extents[i]. /// \p isUnordered specifies whether the loops in the loop nest /// are unordered. +/// +/// NOTE: genLoopNestWithReductions() should be used in favor +/// of this method, though, it cannot generate OpenMP workshare +/// loop constructs currently. LoopNest genLoopNest(mlir::Location loc, fir::FirOpBuilder &builder, mlir::ValueRange extents, bool isUnordered = false, bool emitWorkshareLoop = false); @@ -376,6 +380,37 @@ inline LoopNest genLoopNest(mlir::Location loc, fir::FirOpBuilder &builder, isUnordered, emitWorkshareLoop); } +/// The type of a callback that generates the body of a reduction +/// loop nest. It takes a location and a builder, as usual. +/// In addition, the first set of values are the values of the loops' +/// induction variables. The second set of values are the values +/// of the reductions on entry to the innermost loop. +/// The callback must return the updated values of the reductions. +using ReductionLoopBodyGenerator = std::function( + mlir::Location, fir::FirOpBuilder &, mlir::ValueRange, mlir::ValueRange)>; + +/// Generate a loop nest loopong from 1 to \p extents[i] and reducing +/// a set of values. +/// \p isUnordered specifies whether the loops in the loop nest +/// are unordered. +/// \p reductionInits are the initial values of the reductions +/// on entry to the outermost loop. +/// \p genBody callback is repsonsible for generating the code +/// that updates the reduction values in the innermost loop. +/// +/// NOTE: the implementation of this function may decide +/// to perform the reductions on SSA or in memory. +/// In the latter case, this function is responsible for +/// allocating/loading/storing the reduction variables, +/// and making sure they have proper data sharing attributes +/// in case any parallel constructs are present around the point +/// of the loop nest insertion, or if the function decides +/// to use any worksharing loop constructs for the loop nest. +llvm::SmallVector genLoopNestWithReductions( + mlir::Location loc, fir::FirOpBuilder &builder, mlir::ValueRange extents, + mlir::ValueRange reductionInits, const ReductionLoopBodyGenerator &genBody, + bool isUnordered = false); + /// Inline the body of an hlfir.elemental at the current insertion point /// given a list of one based indices. This generates the computation /// of one element of the elemental expression. Return the YieldElementOp diff --git a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h index e7955c2fc0314..bc0020e614db2 100644 --- a/flang/include/flang/Optimizer/Builder/IntrinsicCall.h +++ b/flang/include/flang/Optimizer/Builder/IntrinsicCall.h @@ -16,7 +16,7 @@ #include "flang/Optimizer/Builder/Runtime/Numeric.h" #include "flang/Optimizer/Builder/Runtime/RTBuilder.h" #include "flang/Runtime/entry-names.h" -#include "flang/Runtime/iostat.h" +#include "flang/Runtime/iostat-consts.h" #include "mlir/Dialect/Complex/IR/Complex.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Dialect/Math/IR/Math.h" diff --git a/flang/include/flang/Optimizer/Builder/MutableBox.h b/flang/include/flang/Optimizer/Builder/MutableBox.h index fea7c7204837b..39657ddaf6e03 100644 --- a/flang/include/flang/Optimizer/Builder/MutableBox.h +++ b/flang/include/flang/Optimizer/Builder/MutableBox.h @@ -14,7 +14,7 @@ #define FORTRAN_OPTIMIZER_BUILDER_MUTABLEBOX_H #include "flang/Optimizer/Builder/BoxValue.h" -#include "flang/Runtime/allocator-registry.h" +#include "flang/Runtime/allocator-registry-consts.h" #include "llvm/ADT/StringRef.h" namespace mlir { diff --git a/flang/include/flang/Optimizer/CodeGen/DescriptorModel.h b/flang/include/flang/Optimizer/CodeGen/DescriptorModel.h index ff0cf29e8073e..9cccf8db87270 100644 --- a/flang/include/flang/Optimizer/CodeGen/DescriptorModel.h +++ b/flang/include/flang/Optimizer/CodeGen/DescriptorModel.h @@ -23,7 +23,7 @@ #define OPTIMIZER_DESCRIPTOR_MODEL_H #include "flang/ISO_Fortran_binding_wrapper.h" -#include "flang/Runtime/descriptor.h" +#include "flang/Runtime/descriptor-consts.h" #include "mlir/Dialect/LLVMIR/LLVMTypes.h" #include "mlir/IR/BuiltinTypes.h" #include "llvm/Support/ErrorHandling.h" diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h b/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h index 447d5fbab8999..15296aa7e8c75 100644 --- a/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h +++ b/flang/include/flang/Optimizer/HLFIR/HLFIRDialect.h @@ -136,6 +136,9 @@ mlir::Value genExprShape(mlir::OpBuilder &builder, const mlir::Location &loc, /// This has to be cleaned up, when HLFIR is the default. bool mayHaveAllocatableComponent(mlir::Type ty); +/// Scalar integer or a sequence of integers (via boxed array or expr). +bool isFortranIntegerScalarOrArrayObject(mlir::Type type); + } // namespace hlfir #endif // FORTRAN_OPTIMIZER_HLFIR_HLFIRDIALECT_H diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td b/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td index d967a407a7588..404ab5f633bf7 100644 --- a/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td +++ b/flang/include/flang/Optimizer/HLFIR/HLFIROpBase.td @@ -155,6 +155,12 @@ def IsPolymorphicObjectPred def AnyPolymorphicObject : Type; +def IsFortranIntegerScalarOrArrayPred + : CPred<"::hlfir::isFortranIntegerScalarOrArrayObject($_self)">; +def AnyFortranIntegerScalarOrArrayObject + : Type; + def hlfir_CharExtremumPredicateAttr : I32EnumAttr< "CharExtremumPredicate", "", [ diff --git a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td index a9826543f48b6..48764580d526d 100644 --- a/flang/include/flang/Optimizer/HLFIR/HLFIROps.td +++ b/flang/include/flang/Optimizer/HLFIR/HLFIROps.td @@ -699,6 +699,27 @@ def hlfir_MatmulTransposeOp : hlfir_Op<"matmul_transpose", let hasVerifier = 1; } +def hlfir_CShiftOp + : hlfir_Op< + "cshift", [DeclareOpInterfaceMethods]> { + let summary = "CSHIFT transformational intrinsic"; + let description = [{ + Circular shift of an array + }]; + + let arguments = (ins AnyFortranArrayObject:$array, + AnyFortranIntegerScalarOrArrayObject:$shift, + Optional:$dim); + + let results = (outs hlfir_ExprType); + + let assemblyFormat = [{ + $array $shift (`dim` $dim^)? attr-dict `:` functional-type(operands, results) + }]; + + let hasVerifier = 1; +} + // An allocation effect is needed because the value produced by the associate // is "deallocated" by hlfir.end_associate (the end_associate must not be // removed, and there must be only one hlfir.end_associate). @@ -1184,6 +1205,7 @@ def hlfir_ShapeOfOp : hlfir_Op<"shape_of", [Pure]> { }]; let builders = [OpBuilder<(ins "mlir::Value":$expr)>]; + let hasFolder = 1; } def hlfir_GetExtentOp : hlfir_Op<"get_extent", [Pure]> { diff --git a/flang/include/flang/Optimizer/Passes/Pipelines.h b/flang/include/flang/Optimizer/Passes/Pipelines.h index b740b38c699e7..337770a776d97 100644 --- a/flang/include/flang/Optimizer/Passes/Pipelines.h +++ b/flang/include/flang/Optimizer/Passes/Pipelines.h @@ -33,16 +33,16 @@ namespace fir { using PassConstructor = std::unique_ptr(); -template -void addNestedPassToOps(mlir::PassManager &pm, PassConstructor ctor) { +template +void addNestedPassToOps(mlir::PassManager &pm, F ctor) { pm.addNestedPass(ctor()); } -template > -void addNestedPassToOps(mlir::PassManager &pm, PassConstructor ctor) { - addNestedPassToOps(pm, ctor); - addNestedPassToOps(pm, ctor); +void addNestedPassToOps(mlir::PassManager &pm, F ctor) { + addNestedPassToOps(pm, ctor); + addNestedPassToOps(pm, ctor); } /// Generic for adding a pass to the pass manager if it is not disabled. @@ -60,11 +60,12 @@ void addNestedPassConditionally(mlir::PassManager &pm, pm.addNestedPass(ctor()); } -void addNestedPassToAllTopLevelOperations(mlir::PassManager &pm, - PassConstructor ctor); +template +void addNestedPassToAllTopLevelOperations(mlir::PassManager &pm, F ctor); +template void addNestedPassToAllTopLevelOperationsConditionally( - mlir::PassManager &pm, llvm::cl::opt &disabled, PassConstructor ctor); + mlir::PassManager &pm, llvm::cl::opt &disabled, F ctor); /// Add MLIR Canonicalizer pass with region simplification disabled. /// FIR does not support the promotion of some SSA value to block arguments (or diff --git a/flang/include/flang/Optimizer/Transforms/CUFCommon.h b/flang/include/flang/Optimizer/Transforms/CUFCommon.h index f019d1893bda4..df1b709dc8608 100644 --- a/flang/include/flang/Optimizer/Transforms/CUFCommon.h +++ b/flang/include/flang/Optimizer/Transforms/CUFCommon.h @@ -9,6 +9,7 @@ #ifndef FORTRAN_OPTIMIZER_TRANSFORMS_CUFCOMMON_H_ #define FORTRAN_OPTIMIZER_TRANSFORMS_CUFCOMMON_H_ +#include "flang/Optimizer/Dialect/FIROps.h" #include "mlir/Dialect/GPU/IR/GPUDialect.h" #include "mlir/IR/BuiltinOps.h" @@ -21,6 +22,7 @@ mlir::gpu::GPUModuleOp getOrCreateGPUModule(mlir::ModuleOp mod, mlir::SymbolTable &symTab); bool isInCUDADeviceContext(mlir::Operation *op); +bool isRegisteredDeviceGlobal(fir::GlobalOp op); } // namespace cuf diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h index 8dd80b7809911..21f0c15cd1489 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.h +++ b/flang/include/flang/Optimizer/Transforms/Passes.h @@ -68,7 +68,6 @@ namespace fir { std::unique_ptr createAffineDemotionPass(); std::unique_ptr createArrayValueCopyPass(fir::ArrayValueCopyOptions options = {}); -std::unique_ptr createCFGConversionPassWithNSW(); std::unique_ptr createMemDataFlowOptPass(); std::unique_ptr createPromoteToAffinePass(); std::unique_ptr @@ -85,7 +84,7 @@ createVScaleAttrPass(std::pair vscaleAttr); void populateCfgConversionRewrites(mlir::RewritePatternSet &patterns, bool forceLoopToExecuteOnce = false, - bool setNSW = false); + bool setNSW = true); // declarative passes #define GEN_PASS_REGISTRATION diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td index 1db41fa7972bf..61f8b0835c958 100644 --- a/flang/include/flang/Optimizer/Transforms/Passes.td +++ b/flang/include/flang/Optimizer/Transforms/Passes.td @@ -153,7 +153,7 @@ def CFGConversion : Pass<"cfg-conversion"> { /*default=*/"false", "force the body of a loop to execute at least once">, Option<"setNSW", "set-nsw", "bool", - /*default=*/"false", + /*default=*/"true", "set nsw on loop variable increment"> ]; } diff --git a/flang/include/flang/Parser/dump-parse-tree.h b/flang/include/flang/Parser/dump-parse-tree.h index c6f35a07d81ea..940caaeea9c3b 100644 --- a/flang/include/flang/Parser/dump-parse-tree.h +++ b/flang/include/flang/Parser/dump-parse-tree.h @@ -488,6 +488,9 @@ class ParseTreeDumper { NODE(parser, OmpAlignment) NODE(parser, OmpAlignedClause) NODE(OmpAlignedClause, Modifier) + NODE(parser, OmpAtClause) + NODE_ENUM(OmpAtClause, ActionTime) + NODE_ENUM(OmpSeverityClause, Severity) NODE(parser, OmpAtomic) NODE(parser, OmpAtomicCapture) NODE(OmpAtomicCapture, Stmt1) @@ -546,6 +549,7 @@ class ParseTreeDumper { NODE(parser, OmpEndCriticalDirective) NODE(parser, OmpEndLoopDirective) NODE(parser, OmpEndSectionsDirective) + NODE(parser, OmpFailClause) NODE(parser, OmpFromClause) NODE(OmpFromClause, Modifier) NODE(parser, OmpExpectation) @@ -558,12 +562,14 @@ class ParseTreeDumper { NODE(parser, OmpLastprivateModifier) NODE_ENUM(OmpLastprivateModifier, Value) NODE(parser, OmpLinearClause) - NODE(OmpLinearClause, WithModifier) - NODE(OmpLinearClause, WithoutModifier) + NODE(OmpLinearClause, Modifier) NODE(parser, OmpLinearModifier) NODE_ENUM(OmpLinearModifier, Value) + NODE(parser, OmpStepComplexModifier) + NODE(parser, OmpStepSimpleModifier) NODE(parser, OmpLoopDirective) NODE(parser, OmpMapClause) + NODE(parser, OmpMessageClause) NODE(OmpMapClause, Modifier) static std::string GetNodeName(const llvm::omp::Clause &x) { return llvm::Twine( @@ -592,7 +598,10 @@ class ParseTreeDumper { NODE(parser, OmpReductionClause) NODE(OmpReductionClause, Modifier) NODE(parser, OmpInReductionClause) + NODE(OmpInReductionClause, Modifier) NODE(parser, OmpReductionCombiner) + NODE(parser, OmpTaskReductionClause) + NODE(OmpTaskReductionClause, Modifier) NODE(OmpReductionCombiner, FunctionCombiner) NODE(parser, OmpReductionInitializerClause) NODE(parser, OmpReductionIdentifier) @@ -604,6 +613,7 @@ class ParseTreeDumper { NODE(parser, OmpScheduleClause) NODE(OmpScheduleClause, Modifier) NODE_ENUM(OmpScheduleClause, Kind) + NODE(parser, OmpSeverityClause) NODE(parser, OmpDeviceClause) NODE(OmpDeviceClause, Modifier) NODE(parser, OmpDeviceModifier) @@ -652,6 +662,7 @@ class ParseTreeDumper { NODE(parser, OmpAtomicDefaultMemOrderClause) NODE_ENUM(common, OmpAtomicDefaultMemOrderType) NODE(parser, OpenMPDepobjConstruct) + NODE(parser, OpenMPErrorConstruct) NODE(parser, OpenMPFlushConstruct) NODE(parser, OpenMPLoopConstruct) NODE(parser, OpenMPExecutableAllocate) diff --git a/flang/include/flang/Parser/parse-tree-visitor.h b/flang/include/flang/Parser/parse-tree-visitor.h index e1ea4d459f4a6..af1d34ae804f3 100644 --- a/flang/include/flang/Parser/parse-tree-visitor.h +++ b/flang/include/flang/Parser/parse-tree-visitor.h @@ -897,40 +897,6 @@ struct ParseTreeVisitorLookupScope { mutator.Post(x); } } - template - static void Walk(const OmpLinearClause::WithModifier &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.modifier, visitor); - Walk(x.names, visitor); - Walk(x.step, visitor); - visitor.Post(x); - } - } - template - static void Walk(OmpLinearClause::WithModifier &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.modifier, mutator); - Walk(x.names, mutator); - Walk(x.step, mutator); - mutator.Post(x); - } - } - template - static void Walk(const OmpLinearClause::WithoutModifier &x, V &visitor) { - if (visitor.Pre(x)) { - Walk(x.names, visitor); - Walk(x.step, visitor); - visitor.Post(x); - } - } - template - static void Walk(OmpLinearClause::WithoutModifier &x, M &mutator) { - if (mutator.Pre(x)) { - Walk(x.names, mutator); - Walk(x.step, mutator); - mutator.Post(x); - } - } }; } // namespace detail diff --git a/flang/include/flang/Parser/parse-tree.h b/flang/include/flang/Parser/parse-tree.h index 8160b095f06dd..1d97126d17dbc 100644 --- a/flang/include/flang/Parser/parse-tree.h +++ b/flang/include/flang/Parser/parse-tree.h @@ -269,6 +269,7 @@ struct OpenACCRoutineConstruct; struct OpenMPConstruct; struct OpenMPDeclarativeConstruct; struct OmpEndLoopDirective; +struct OmpMemoryOrderClause; struct CUFKernelDoConstruct; // Cooked character stream locations @@ -3698,6 +3699,22 @@ struct OmpReductionModifier { WRAPPER_CLASS_BOILERPLATE(OmpReductionModifier, Value); }; +// Ref: [5.2:117-120] +// +// step-complex-modifier -> +// STEP(integer-expression) // since 5.2 +struct OmpStepComplexModifier { + WRAPPER_CLASS_BOILERPLATE(OmpStepComplexModifier, ScalarIntExpr); +}; + +// Ref: [4.5:207-210], [5.0:290-293], [5.1:323-325], [5.2:117-120] +// +// step-simple-modifier -> +// integer-expresion // since 4.5 +struct OmpStepSimpleModifier { + WRAPPER_CLASS_BOILERPLATE(OmpStepSimpleModifier, ScalarIntExpr); +}; + // Ref: [4.5:169-170], [5.0:254-256], [5.1:287-289], [5.2:321] // // task-dependence-type -> // "dependence-type" in 5.1 and before @@ -3761,6 +3778,13 @@ struct OmpAllocateClause { std::tuple t; }; +// Ref: [5.2:216-217 (sort of, as it's only mentioned in passing) +// AT(compilation|execution) +struct OmpAtClause { + ENUM_CLASS(ActionTime, Compilation, Execution); + WRAPPER_CLASS_BOILERPLATE(OmpAtClause, ActionTime); +}; + // Ref: [5.0:60-63], [5.1:83-86], [5.2:210-213] // // atomic-default-mem-order-clause -> @@ -3914,6 +3938,14 @@ struct OmpDeviceTypeClause { WRAPPER_CLASS_BOILERPLATE(OmpDeviceTypeClause, DeviceTypeDescription); }; +// OMP 5.2 15.8.3 extended-atomic, fail-clause -> +// FAIL(memory-order) +struct OmpFailClause { + WRAPPER_CLASS_BOILERPLATE( + OmpFailClause, common::Indirection); + CharBlock source; +}; + // Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168] // // from-clause -> @@ -3925,7 +3957,7 @@ struct OmpDeviceTypeClause { struct OmpFromClause { TUPLE_CLASS_BOILERPLATE(OmpFromClause); MODIFIER_BOILERPLATE(OmpExpectation, OmpIterator, OmpMapper); - std::tuple t; + std::tuple t; }; // Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:269] @@ -3951,11 +3983,14 @@ struct OmpIfClause { std::tuple t; }; -// OMP 5.0 2.19.5.6 in_reduction-clause -> IN_REDUCTION (reduction-identifier: -// variable-name-list) +// Ref: [5.0:170-176], [5.1:197-205], [5.2:138-139] +// +// in-reduction-clause -> +// IN_REDUCTION(reduction-identifier: list) // since 5.0 struct OmpInReductionClause { TUPLE_CLASS_BOILERPLATE(OmpInReductionClause); - std::tuple t; + MODIFIER_BOILERPLATE(OmpReductionIdentifier); + std::tuple t; }; // Ref: [4.5:199-201], [5.0:288-290], [5.1:321-322], [5.2:115-117] @@ -3969,28 +4004,20 @@ struct OmpLastprivateClause { std::tuple t; }; -// 2.15.3.7 linear-clause -> LINEAR (linear-list[ : linear-step]) -// linear-list -> list | linear-modifier(list) +// Ref: [4.5:207-210], [5.0:290-293], [5.1:323-325], [5.2:117-120] +// +// linear-clause -> +// LINEAR(list [: step-simple-modifier]) | // since 4.5 +// LINEAR(linear-modifier(list) +// [: step-simple-modifier]) | // since 4.5, until 5.2[*] +// LINEAR(list [: linear-modifier, +// step-complex-modifier]) // since 5.2 +// [*] Still allowed in 5.2 when on DECLARE SIMD, but deprecated. struct OmpLinearClause { - UNION_CLASS_BOILERPLATE(OmpLinearClause); - struct WithModifier { - BOILERPLATE(WithModifier); - WithModifier(OmpLinearModifier &&m, std::list &&n, - std::optional &&s) - : modifier(std::move(m)), names(std::move(n)), step(std::move(s)) {} - OmpLinearModifier modifier; - std::list names; - std::optional step; - }; - struct WithoutModifier { - BOILERPLATE(WithoutModifier); - WithoutModifier( - std::list &&n, std::optional &&s) - : names(std::move(n)), step(std::move(s)) {} - std::list names; - std::optional step; - }; - std::variant u; + TUPLE_CLASS_BOILERPLATE(OmpLinearClause); + MODIFIER_BOILERPLATE( + OmpLinearModifier, OmpStepSimpleModifier, OmpStepComplexModifier); + std::tuple t; }; // Ref: [4.5:216-219], [5.0:315-324], [5.1:347-355], [5.2:150-158] @@ -4005,7 +4032,14 @@ struct OmpLinearClause { struct OmpMapClause { TUPLE_CLASS_BOILERPLATE(OmpMapClause); MODIFIER_BOILERPLATE(OmpMapTypeModifier, OmpMapper, OmpIterator, OmpMapType); - std::tuple t; + std::tuple t; +}; + +// Ref: [5.2:217-218] +// message-clause -> +// MESSAGE("message-text") +struct OmpMessageClause { + WRAPPER_CLASS_BOILERPLATE(OmpMessageClause, Expr); }; // Ref: [4.5:87-91], [5.0:140-146], [5.1:166-171], [5.2:270] @@ -4070,6 +4104,24 @@ struct OmpScheduleClause { std::tuple> t; }; +// REF: [5.2:217] +// severity-clause -> +// SEVERITY(warning|fatal) +struct OmpSeverityClause { + ENUM_CLASS(Severity, Fatal, Warning); + WRAPPER_CLASS_BOILERPLATE(OmpSeverityClause, Severity); +}; + +// Ref: [5.0:232-234], [5.1:264-266], [5.2:137] +// +// task-reduction-clause -> +// TASK_REDUCTION(reduction-identifier: list) // since 5.0 +struct OmpTaskReductionClause { + TUPLE_CLASS_BOILERPLATE(OmpTaskReductionClause); + MODIFIER_BOILERPLATE(OmpReductionIdentifier); + std::tuple t; +}; + // Ref: [4.5:107-109], [5.0:176-180], [5.1:205-210], [5.2:167-168] // // to-clause (in DECLARE TARGET) -> @@ -4083,7 +4135,7 @@ struct OmpScheduleClause { struct OmpToClause { TUPLE_CLASS_BOILERPLATE(OmpToClause); MODIFIER_BOILERPLATE(OmpExpectation, OmpIterator, OmpMapper); - std::tuple t; + std::tuple t; }; // Ref: [5.0:254-255], [5.1:287-288], [5.2:321-322] @@ -4317,11 +4369,12 @@ struct OmpMemoryOrderClause { }; // 2.17.7 Atomic construct -// atomic-clause -> memory-order-clause | HINT(hint-expression) +// atomic-clause -> memory-order-clause | HINT(hint-expression) | +// FAIL(memory-order) struct OmpAtomicClause { UNION_CLASS_BOILERPLATE(OmpAtomicClause); CharBlock source; - std::variant u; + std::variant u; }; // atomic-clause-list -> [atomic-clause, [atomic-clause], ...] @@ -4445,6 +4498,14 @@ struct OpenMPDepobjConstruct { std::tuple t; }; +// Ref: OpenMP [5.2:216-218] +// ERROR AT(compilation|execution) SEVERITY(fatal|warning) MESSAGE("msg-str) +struct OpenMPErrorConstruct { + TUPLE_CLASS_BOILERPLATE(OpenMPErrorConstruct); + CharBlock source; + std::tuple t; +}; + // 2.17.8 flush -> FLUSH [memory-order-clause] [(variable-name-list)] struct OpenMPFlushConstruct { TUPLE_CLASS_BOILERPLATE(OpenMPFlushConstruct); @@ -4517,7 +4578,7 @@ struct OpenMPConstruct { UNION_CLASS_BOILERPLATE(OpenMPConstruct); std::variant u; diff --git a/flang/include/flang/Runtime/CUDA/allocatable.h b/flang/include/flang/Runtime/CUDA/allocatable.h index e2156281d1b2b..0a96f73b6be44 100644 --- a/flang/include/flang/Runtime/CUDA/allocatable.h +++ b/flang/include/flang/Runtime/CUDA/allocatable.h @@ -9,7 +9,7 @@ #ifndef FORTRAN_RUNTIME_CUDA_ALLOCATABLE_H_ #define FORTRAN_RUNTIME_CUDA_ALLOCATABLE_H_ -#include "flang/Runtime/descriptor.h" +#include "flang/Runtime/descriptor-consts.h" #include "flang/Runtime/entry-names.h" namespace Fortran::runtime::cuda { diff --git a/flang/include/flang/Runtime/CUDA/allocator.h b/flang/include/flang/Runtime/CUDA/allocator.h index 40423c5ce0488..4fb4c94c5e9b0 100644 --- a/flang/include/flang/Runtime/CUDA/allocator.h +++ b/flang/include/flang/Runtime/CUDA/allocator.h @@ -9,7 +9,8 @@ #ifndef FORTRAN_RUNTIME_CUDA_ALLOCATOR_H_ #define FORTRAN_RUNTIME_CUDA_ALLOCATOR_H_ -#include "flang/Runtime/descriptor.h" +#include "common.h" +#include "flang/Runtime/descriptor-consts.h" #include "flang/Runtime/entry-names.h" namespace Fortran::runtime::cuda { @@ -19,16 +20,16 @@ extern "C" { void RTDECL(CUFRegisterAllocator)(); } -void *CUFAllocPinned(std::size_t, std::int64_t); +void *CUFAllocPinned(std::size_t); void CUFFreePinned(void *); -void *CUFAllocDevice(std::size_t, std::int64_t); +void *CUFAllocDevice(std::size_t); void CUFFreeDevice(void *); -void *CUFAllocManaged(std::size_t, std::int64_t); +void *CUFAllocManaged(std::size_t); void CUFFreeManaged(void *); -void *CUFAllocUnified(std::size_t, std::int64_t); +void *CUFAllocUnified(std::size_t); void CUFFreeUnified(void *); } // namespace Fortran::runtime::cuda diff --git a/flang/include/flang/Runtime/CUDA/common.h b/flang/include/flang/Runtime/CUDA/common.h index 8172ea39a14f8..474f8e6578b89 100644 --- a/flang/include/flang/Runtime/CUDA/common.h +++ b/flang/include/flang/Runtime/CUDA/common.h @@ -9,7 +9,7 @@ #ifndef FORTRAN_RUNTIME_CUDA_COMMON_H_ #define FORTRAN_RUNTIME_CUDA_COMMON_H_ -#include "flang/Runtime/descriptor.h" +#include "flang/Runtime/descriptor-consts.h" #include "flang/Runtime/entry-names.h" /// Type of memory for allocation/deallocation @@ -23,9 +23,6 @@ static constexpr unsigned kHostToDevice = 0; static constexpr unsigned kDeviceToHost = 1; static constexpr unsigned kDeviceToDevice = 2; -/// Value used for asyncId when no specific stream is specified. -static constexpr std::int64_t kCudaNoStream = -1; - #define CUDA_REPORT_IF_ERROR(expr) \ [](cudaError_t err) { \ if (err == cudaSuccess) \ diff --git a/flang/include/flang/Runtime/CUDA/descriptor.h b/flang/include/flang/Runtime/CUDA/descriptor.h index 93791012fdcc7..4c6c2c4694fd4 100644 --- a/flang/include/flang/Runtime/CUDA/descriptor.h +++ b/flang/include/flang/Runtime/CUDA/descriptor.h @@ -9,7 +9,7 @@ #ifndef FORTRAN_RUNTIME_CUDA_DESCRIPTOR_H_ #define FORTRAN_RUNTIME_CUDA_DESCRIPTOR_H_ -#include "flang/Runtime/descriptor.h" +#include "flang/Runtime/descriptor-consts.h" #include "flang/Runtime/entry-names.h" #include diff --git a/flang/include/flang/Runtime/CUDA/memory.h b/flang/include/flang/Runtime/CUDA/memory.h index 2bb083b0dd75c..fbe4941260ff9 100644 --- a/flang/include/flang/Runtime/CUDA/memory.h +++ b/flang/include/flang/Runtime/CUDA/memory.h @@ -9,7 +9,7 @@ #ifndef FORTRAN_RUNTIME_CUDA_MEMORY_H_ #define FORTRAN_RUNTIME_CUDA_MEMORY_H_ -#include "flang/Runtime/descriptor.h" +#include "flang/Runtime/descriptor-consts.h" #include "flang/Runtime/entry-names.h" #include diff --git a/flang/include/flang/Runtime/allocatable.h b/flang/include/flang/Runtime/allocatable.h index 121c31af963aa..58061d9862095 100644 --- a/flang/include/flang/Runtime/allocatable.h +++ b/flang/include/flang/Runtime/allocatable.h @@ -94,9 +94,9 @@ int RTDECL(AllocatableCheckLengthParameter)(Descriptor &, // Successfully allocated memory is initialized if the allocatable has a // derived type, and is always initialized by AllocatableAllocateSource(). // Performs all necessary coarray synchronization and validation actions. -int RTDECL(AllocatableAllocate)(Descriptor &, std::int64_t asyncId = -1, - bool hasStat = false, const Descriptor *errMsg = nullptr, - const char *sourceFile = nullptr, int sourceLine = 0); +int RTDECL(AllocatableAllocate)(Descriptor &, bool hasStat = false, + const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, + int sourceLine = 0); int RTDECL(AllocatableAllocateSource)(Descriptor &, const Descriptor &source, bool hasStat = false, const Descriptor *errMsg = nullptr, const char *sourceFile = nullptr, int sourceLine = 0); diff --git a/flang/include/flang/Runtime/allocator-registry-consts.h b/flang/include/flang/Runtime/allocator-registry-consts.h new file mode 100644 index 0000000000000..a5f52749e945d --- /dev/null +++ b/flang/include/flang/Runtime/allocator-registry-consts.h @@ -0,0 +1,24 @@ +//===-- include/flang/Runtime/allocator-registry-consts.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_RUNTIME_ALLOCATOR_REGISTRY_CONSTS_H_ +#define FORTRAN_RUNTIME_ALLOCATOR_REGISTRY_CONSTS_H_ + +RT_OFFLOAD_VAR_GROUP_BEGIN + +static constexpr unsigned kDefaultAllocator = 0; + +// Allocator used for CUF +static constexpr unsigned kPinnedAllocatorPos = 1; +static constexpr unsigned kDeviceAllocatorPos = 2; +static constexpr unsigned kManagedAllocatorPos = 3; +static constexpr unsigned kUnifiedAllocatorPos = 4; + +RT_OFFLOAD_VAR_GROUP_END + +#endif /* FORTRAN_RUNTIME_ALLOCATOR_REGISTRY_CONSTS_H_ */ diff --git a/flang/include/flang/Runtime/allocator-registry.h b/flang/include/flang/Runtime/allocator-registry.h index b1d00beba25aa..29302c5d825bc 100644 --- a/flang/include/flang/Runtime/allocator-registry.h +++ b/flang/include/flang/Runtime/allocator-registry.h @@ -10,27 +10,15 @@ #define FORTRAN_RUNTIME_ALLOCATOR_REGISTRY_H_ #include "flang/Common/api-attrs.h" -#include +#include "flang/Runtime/allocator-registry-consts.h" #include #include -RT_OFFLOAD_VAR_GROUP_BEGIN - -static constexpr unsigned kDefaultAllocator = 0; - -// Allocator used for CUF -static constexpr unsigned kPinnedAllocatorPos = 1; -static constexpr unsigned kDeviceAllocatorPos = 2; -static constexpr unsigned kManagedAllocatorPos = 3; -static constexpr unsigned kUnifiedAllocatorPos = 4; - -RT_OFFLOAD_VAR_GROUP_END - #define MAX_ALLOCATOR 7 // 3 bits are reserved in the descriptor. namespace Fortran::runtime { -using AllocFct = void *(*)(std::size_t, std::int64_t); +using AllocFct = void *(*)(std::size_t); using FreeFct = void (*)(void *); typedef struct Allocator_t { @@ -38,11 +26,10 @@ typedef struct Allocator_t { FreeFct free{nullptr}; } Allocator_t; -static RT_API_ATTRS void *MallocWrapper( - std::size_t size, [[maybe_unused]] std::int64_t) { +#ifdef RT_DEVICE_COMPILATION +static RT_API_ATTRS void *MallocWrapper(std::size_t size) { return std::malloc(size); } -#ifdef RT_DEVICE_COMPILATION static RT_API_ATTRS void FreeWrapper(void *p) { return std::free(p); } #endif @@ -52,7 +39,7 @@ struct AllocatorRegistry { : allocators{{&MallocWrapper, &FreeWrapper}} {} #else constexpr AllocatorRegistry() { - allocators[kDefaultAllocator] = {&MallocWrapper, &std::free}; + allocators[kDefaultAllocator] = {&std::malloc, &std::free}; }; #endif RT_API_ATTRS void Register(int, Allocator_t); diff --git a/flang/include/flang/Runtime/array-constructor-consts.h b/flang/include/flang/Runtime/array-constructor-consts.h new file mode 100644 index 0000000000000..ad3583eef29aa --- /dev/null +++ b/flang/include/flang/Runtime/array-constructor-consts.h @@ -0,0 +1,97 @@ +//===-- include/flang/Runtime/array-constructor-consts.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_RUNTIME_ARRAY_CONSTRUCTOR_CONSTS_H_ +#define FORTRAN_RUNTIME_ARRAY_CONSTRUCTOR_CONSTS_H_ + +#include "flang/Runtime/descriptor-consts.h" +#include "flang/Runtime/entry-names.h" +#include + +namespace Fortran::runtime { +struct ArrayConstructorVector; + +// Max sizeof(ArrayConstructorVector) and sizeof(ArrayConstructorVector) for any +// target. +// TODO: Use target-specific size/alignment instead of overapproximation. +constexpr std::size_t MaxArrayConstructorVectorSizeInBytes = 2 * 40; +constexpr std::size_t MaxArrayConstructorVectorAlignInBytes = 8; + +// This file defines an API to "push" an evaluated array constructor value +// "from" into some storage "to" of an array constructor. It can be seen as a +// form of std::vector::push_back() implementation for Fortran array +// constructors. In the APIs and ArrayConstructorVector struct above: +// +// - "to" is a ranked-1 descriptor whose declared type is already set to the +// array constructor derived type. It may be already allocated, even before the +// first call to this API, or it may be unallocated. "to" extent is increased +// every time a "from" is pushed past its current extent. At this end of the +// API calls, its extent is the extent of the array constructor. If "to" is +// unallocated and its extent is not null, it is assumed this is the final array +// constructor extent value, and the first allocation already "reserves" storage +// space accordingly to avoid reallocations. +// - "from" is a scalar or array descriptor for the evaluated array +// constructor value that must be copied into the storage of "to" at +// "nextValuePosition". +// - "useValueLengthParameters" must be set to true if the array constructor +// has length parameters and no type spec. If it is true and "to" is +// unallocated, "to" will take the length parameters of "from". If it is true +// and "to" is an allocated character array constructor, it will be checked +// that "from" length matches the one from "to". When it is false, the +// character length must already be set in "to" before the first call to this +// API and "from" character lengths are allowed to mismatch from "to". +// - "nextValuePosition" is the zero based sequence position of "from" in the +// array constructor. It is updated after this call by the number of "from" +// elements. It should be set to zero by the caller of this API before the first +// call. +// - "actualAllocationSize" is the current allocation size of "to" storage. It +// may be bigger than "to" extent for reallocation optimization purposes, but +// should never be smaller, unless this is the first call and "to" is +// unallocated. It is updated by the runtime after each successful allocation or +// reallocation. It should be set to "to" extent if "to" is allocated before the +// first call of this API, and can be left undefined otherwise. +// +// Note that this API can be used with "to" being a variable (that can be +// discontiguous). This can be done when the variable is the left hand side of +// an assignment from an array constructor as long as: +// - none of the ac-value overlaps with the variable, +// - this is an intrinsic assignment that is not a whole allocatable +// assignment, *and* for a type that has no components requiring user defined +// assignments, +// - the variable is properly finalized before using this API if its need to, +// - "useValueLengthParameters" should be set to false in this case, even if +// the array constructor has no type-spec, since the variable may have a +// different character length than the array constructor values. + +extern "C" { +// API to initialize an ArrayConstructorVector before any values are pushed to +// it. Inlined code is only expected to allocate the "ArrayConstructorVector" +// class instance storage with sufficient size +// (MaxArrayConstructorVectorSizeInBytes is expected to be large enough for all +// supported targets). This avoids the need for the runtime to maintain a state, +// or to use dynamic allocation for it. +void RTDECL(InitArrayConstructorVector)(ArrayConstructorVector &vector, + Descriptor &to, bool useValueLengthParameters, + const char *sourceFile = nullptr, int sourceLine = 0); + +// Generic API to push any kind of entity into the array constructor (any +// Fortran type and any rank). +void RTDECL(PushArrayConstructorValue)( + ArrayConstructorVector &vector, const Descriptor &from); + +// API to push scalar array constructor value of: +// - a numerical or logical type, +// - or a derived type that has no length parameters, and no allocatable +// component (that would require deep copies). +// It requires no descriptor for the value that is passed via its base address. +void RTDECL(PushArrayConstructorSimpleScalar)( + ArrayConstructorVector &vector, void *from); +} // extern "C" +} // namespace Fortran::runtime + +#endif /* FORTRAN_RUNTIME_ARRAY_CONSTRUCTOR_CONSTS_H_ */ diff --git a/flang/include/flang/Runtime/array-constructor.h b/flang/include/flang/Runtime/array-constructor.h index 46fc0418c7991..2f6aaae17c650 100644 --- a/flang/include/flang/Runtime/array-constructor.h +++ b/flang/include/flang/Runtime/array-constructor.h @@ -12,6 +12,7 @@ #ifndef FORTRAN_RUNTIME_ARRAYCONSTRUCTOR_H_ #define FORTRAN_RUNTIME_ARRAYCONSTRUCTOR_H_ +#include "flang/Runtime/array-constructor-consts.h" #include "flang/Runtime/descriptor.h" #include "flang/Runtime/entry-names.h" #include @@ -43,76 +44,14 @@ struct ArrayConstructorVector { unsigned char useValueLengthParameters_ : 1; }; -// This file defines an API to "push" an evaluated array constructor value -// "from" into some storage "to" of an array constructor. It can be seen as a -// form of std::vector::push_back() implementation for Fortran array -// constructors. In the APIs and ArrayConstructorVector struct above: -// -// - "to" is a ranked-1 descriptor whose declared type is already set to the -// array constructor derived type. It may be already allocated, even before the -// first call to this API, or it may be unallocated. "to" extent is increased -// every time a "from" is pushed past its current extent. At this end of the -// API calls, its extent is the extent of the array constructor. If "to" is -// unallocated and its extent is not null, it is assumed this is the final array -// constructor extent value, and the first allocation already "reserves" storage -// space accordingly to avoid reallocations. -// - "from" is a scalar or array descriptor for the evaluated array -// constructor value that must be copied into the storage of "to" at -// "nextValuePosition". -// - "useValueLengthParameters" must be set to true if the array constructor -// has length parameters and no type spec. If it is true and "to" is -// unallocated, "to" will take the length parameters of "from". If it is true -// and "to" is an allocated character array constructor, it will be checked -// that "from" length matches the one from "to". When it is false, the -// character length must already be set in "to" before the first call to this -// API and "from" character lengths are allowed to mismatch from "to". -// - "nextValuePosition" is the zero based sequence position of "from" in the -// array constructor. It is updated after this call by the number of "from" -// elements. It should be set to zero by the caller of this API before the first -// call. -// - "actualAllocationSize" is the current allocation size of "to" storage. It -// may be bigger than "to" extent for reallocation optimization purposes, but -// should never be smaller, unless this is the first call and "to" is -// unallocated. It is updated by the runtime after each successful allocation or -// reallocation. It should be set to "to" extent if "to" is allocated before the -// first call of this API, and can be left undefined otherwise. -// -// Note that this API can be used with "to" being a variable (that can be -// discontiguous). This can be done when the variable is the left hand side of -// an assignment from an array constructor as long as: -// - none of the ac-value overlaps with the variable, -// - this is an intrinsic assignment that is not a whole allocatable -// assignment, *and* for a type that has no components requiring user defined -// assignments, -// - the variable is properly finalized before using this API if its need to, -// - "useValueLengthParameters" should be set to false in this case, even if -// the array constructor has no type-spec, since the variable may have a -// different character length than the array constructor values. - -extern "C" { -// API to initialize an ArrayConstructorVector before any values are pushed to -// it. Inlined code is only expected to allocate the "ArrayConstructorVector" -// class instance storage with sufficient size (using -// "2*sizeof(ArrayConstructorVector)" on the host should be safe regardless of -// the target the runtime is compiled for). This avoids the need for the runtime -// to maintain a state, or to use dynamic allocation for it. "vectorClassSize" -// is used to validate that lowering allocated enough space for it. -void RTDECL(InitArrayConstructorVector)(ArrayConstructorVector &vector, - Descriptor &to, bool useValueLengthParameters, int vectorClassSize, - const char *sourceFile = nullptr, int sourceLine = 0); - -// Generic API to push any kind of entity into the array constructor (any -// Fortran type and any rank). -void RTDECL(PushArrayConstructorValue)( - ArrayConstructorVector &vector, const Descriptor &from); +static_assert(sizeof(Fortran::runtime::ArrayConstructorVector) <= + MaxArrayConstructorVectorSizeInBytes, + "ABI requires sizeof(ArrayConstructorVector) to be smaller than " + "MaxArrayConstructorVectorSizeInBytes"); +static_assert(alignof(Fortran::runtime::ArrayConstructorVector) <= + MaxArrayConstructorVectorAlignInBytes, + "ABI requires alignof(ArrayConstructorVector) to be smaller than " + "MaxArrayConstructorVectorAlignInBytes"); -// API to push scalar array constructor value of: -// - a numerical or logical type, -// - or a derived type that has no length parameters, and no allocatable -// component (that would require deep copies). -// It requires no descriptor for the value that is passed via its base address. -void RTDECL(PushArrayConstructorSimpleScalar)( - ArrayConstructorVector &vector, void *from); -} // extern "C" } // namespace Fortran::runtime #endif // FORTRAN_RUNTIME_ARRAYCONSTRUCTOR_H_ diff --git a/flang/include/flang/Runtime/descriptor-consts.h b/flang/include/flang/Runtime/descriptor-consts.h new file mode 100644 index 0000000000000..3b2537579d586 --- /dev/null +++ b/flang/include/flang/Runtime/descriptor-consts.h @@ -0,0 +1,74 @@ +//===-- include/flang/Runtime/descriptor-consts.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_RUNTIME_DESCRIPTOR_CONSTS_H_ +#define FORTRAN_RUNTIME_DESCRIPTOR_CONSTS_H_ + +#include "flang/Common/api-attrs.h" +#include "flang/ISO_Fortran_binding_wrapper.h" +#include +#include + +// Value of the addendum presence flag. +#define _CFI_ADDENDUM_FLAG 1 +// Number of bits needed to be shifted when manipulating the allocator index. +#define _CFI_ALLOCATOR_IDX_SHIFT 1 +// Allocator index mask. +#define _CFI_ALLOCATOR_IDX_MASK 0b00001110 + +namespace Fortran::runtime::typeInfo { +using TypeParameterValue = std::int64_t; +class DerivedType; +} // namespace Fortran::runtime::typeInfo + +namespace Fortran::runtime { +class Descriptor; +using SubscriptValue = ISO::CFI_index_t; + +/// Returns size in bytes of the descriptor (not the data) +/// This must be at least as large as the largest descriptor of any target +/// triple. +static constexpr RT_API_ATTRS std::size_t MaxDescriptorSizeInBytes( + int rank, bool addendum = false, int lengthTypeParameters = 0) { + // Layout: + // + // fortran::runtime::Descriptor { + // ISO::CFI_cdesc_t { + // void *base_addr; (pointer -> up to 8 bytes) + // size_t elem_len; (up to 8 bytes) + // int version; (up to 4 bytes) + // CFI_rank_t rank; (unsigned char -> 1 byte) + // CFI_type_t type; (signed char -> 1 byte) + // CFI_attribute_t attribute; (unsigned char -> 1 byte) + // unsigned char extra; (1 byte) + // } + // } + // fortran::runtime::Dimension[rank] { + // ISO::CFI_dim_t { + // CFI_index_t lower_bound; (ptrdiff_t -> up to 8 bytes) + // CFI_index_t extent; (ptrdiff_t -> up to 8 bytes) + // CFI_index_t sm; (ptrdiff_t -> up to 8 bytes) + // } + // } + // fortran::runtime::DescriptorAddendum { + // const typeInfo::DerivedType *derivedType_; (pointer -> up to 8 + // bytes) typeInfo::TypeParameterValue len_[lenParameters]; (int64_t -> 8 + // bytes) + // } + std::size_t bytes{24u + rank * 24u}; + if (addendum || lengthTypeParameters > 0) { + if (lengthTypeParameters < 1) + lengthTypeParameters = 1; + bytes += 8u + static_cast(lengthTypeParameters) * 8u; + } + return bytes; +} + +} // namespace Fortran::runtime + +#endif /* FORTRAN_RUNTIME_DESCRIPTOR_CONSTS_H_ */ diff --git a/flang/include/flang/Runtime/descriptor.h b/flang/include/flang/Runtime/descriptor.h index e6300accfeac0..dd36fba157ca9 100644 --- a/flang/include/flang/Runtime/descriptor.h +++ b/flang/include/flang/Runtime/descriptor.h @@ -19,6 +19,7 @@ // but should never reference this internal header. #include "flang/ISO_Fortran_binding_wrapper.h" +#include "flang/Runtime/descriptor-consts.h" #include "flang/Runtime/memory.h" #include "flang/Runtime/type-code.h" #include @@ -28,14 +29,8 @@ #include #include -namespace Fortran::runtime::typeInfo { -using TypeParameterValue = std::int64_t; -class DerivedType; -} // namespace Fortran::runtime::typeInfo - namespace Fortran::runtime { -using SubscriptValue = ISO::CFI_index_t; class Terminator; RT_VAR_GROUP_BEGIN @@ -374,7 +369,7 @@ class Descriptor { // before calling. It (re)computes the byte strides after // allocation. Does not allocate automatic components or // perform default component initialization. - RT_API_ATTRS int Allocate(std::int64_t asyncId = -1); + RT_API_ATTRS int Allocate(); RT_API_ATTRS void SetByteStrides(); // Deallocates storage; does not call FINAL subroutines or @@ -420,13 +415,6 @@ class Descriptor { void Dump(FILE * = stdout) const; -// Value of the addendum presence flag. -#define _CFI_ADDENDUM_FLAG 1 -// Number of bits needed to be shifted when manipulating the allocator index. -#define _CFI_ALLOCATOR_IDX_SHIFT 1 -// Allocator index mask. -#define _CFI_ALLOCATOR_IDX_MASK 0b00001110 - RT_API_ATTRS inline bool HasAddendum() const { return raw_.extra & _CFI_ADDENDUM_FLAG; } @@ -464,6 +452,8 @@ class alignas(Descriptor) StaticDescriptor { static constexpr bool hasAddendum{ADDENDUM || MAX_LEN_PARMS > 0}; static constexpr std::size_t byteSize{ Descriptor::SizeInBytes(maxRank, hasAddendum, maxLengthTypeParameters)}; + static_assert(byteSize <= + MaxDescriptorSizeInBytes(maxRank, hasAddendum, maxLengthTypeParameters)); RT_OFFLOAD_VAR_GROUP_END RT_API_ATTRS Descriptor &descriptor() { diff --git a/flang/include/flang/Runtime/io-api-consts.h b/flang/include/flang/Runtime/io-api-consts.h new file mode 100644 index 0000000000000..7ed8bf1489b3c --- /dev/null +++ b/flang/include/flang/Runtime/io-api-consts.h @@ -0,0 +1,368 @@ +//===-- include/flang/Runtime/io-api-consts.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_RUNTIME_IO_API_CONSTS_H_ +#define FORTRAN_RUNTIME_IO_API_CONSTS_H_ + +#include "flang/Common/uint128.h" +#include "flang/Runtime/entry-names.h" +#include "flang/Runtime/iostat-consts.h" +#include "flang/Runtime/magic-numbers.h" +#include +#include + +namespace Fortran::runtime { +class Descriptor; +} // namespace Fortran::runtime + +namespace Fortran::runtime::io { + +struct NonTbpDefinedIoTable; +class NamelistGroup; +class IoStatementState; +using Cookie = IoStatementState *; +using ExternalUnit = int; +using AsynchronousId = int; + +static constexpr ExternalUnit DefaultOutputUnit{FORTRAN_DEFAULT_OUTPUT_UNIT}; +static constexpr ExternalUnit DefaultInputUnit{FORTRAN_DEFAULT_INPUT_UNIT}; + +// INQUIRE specifiers are encoded as simple base-26 packings of +// the spellings of their keywords. +using InquiryKeywordHash = std::uint64_t; +constexpr InquiryKeywordHash HashInquiryKeyword(const char *p) { + InquiryKeywordHash hash{1}; + while (char ch{*p++}) { + std::uint64_t letter{0}; + if (ch >= 'a' && ch <= 'z') { + letter = ch - 'a'; + } else { + letter = ch - 'A'; + } + hash = 26 * hash + letter; + } + return hash; +} + +extern "C" { + +#define IONAME(name) RTNAME(io##name) + +#ifndef IODECL +#define IODECL(name) RT_API_ATTRS IONAME(name) +#endif + +#ifndef IODEF +#define IODEF(name) RT_API_ATTRS IONAME(name) +#endif + +// These functions initiate data transfer statements (READ, WRITE, PRINT). +// Example: PRINT *, 666 is implemented as the series of calls: +// Cookie cookie{BeginExternalListOutput(DefaultOutputUnit, +// __FILE__, __LINE__)}; +// OutputInteger32(cookie, 666); +// EndIoStatement(cookie); +// Formatted I/O with explicit formats can supply the format as a +// const char * pointer with a length, or with a descriptor. + +// Internal I/O initiation +// Internal I/O can loan the runtime library an optional block of memory +// in which the library can maintain state across the calls that implement +// the internal transfer; use of these blocks can reduce the need for dynamic +// memory allocation &/or thread-local storage. The block must be sufficiently +// aligned to hold a pointer. +constexpr std::size_t RecommendedInternalIoScratchAreaBytes( + int maxFormatParenthesesNestingDepth) { + return 32 + 8 * maxFormatParenthesesNestingDepth; +} + +// For NAMELIST I/O, use the API for the appropriate form of list-directed +// I/O initiation and configuration, then call OutputNamelist/InputNamelist +// below. + +// Internal I/O to/from character arrays &/or non-default-kind character +// requires a descriptor, which is copied. +Cookie IODECL(BeginInternalArrayListOutput)(const Descriptor &, + void **scratchArea = nullptr, std::size_t scratchBytes = 0, + const char *sourceFile = nullptr, int sourceLine = 0); +Cookie IODECL(BeginInternalArrayListInput)(const Descriptor &, + void **scratchArea = nullptr, std::size_t scratchBytes = 0, + const char *sourceFile = nullptr, int sourceLine = 0); +Cookie IODECL(BeginInternalArrayFormattedOutput)(const Descriptor &, + const char *format, std::size_t formatLength, + const Descriptor *formatDescriptor = nullptr, void **scratchArea = nullptr, + std::size_t scratchBytes = 0, const char *sourceFile = nullptr, + int sourceLine = 0); +Cookie IODECL(BeginInternalArrayFormattedInput)(const Descriptor &, + const char *format, std::size_t formatLength, + const Descriptor *formatDescriptor = nullptr, void **scratchArea = nullptr, + std::size_t scratchBytes = 0, const char *sourceFile = nullptr, + int sourceLine = 0); + +// Internal I/O to/from a default-kind character scalar can avoid a +// descriptor. +Cookie IODECL(BeginInternalListOutput)(char *internal, + std::size_t internalLength, void **scratchArea = nullptr, + std::size_t scratchBytes = 0, const char *sourceFile = nullptr, + int sourceLine = 0); +Cookie IODECL(BeginInternalListInput)(const char *internal, + std::size_t internalLength, void **scratchArea = nullptr, + std::size_t scratchBytes = 0, const char *sourceFile = nullptr, + int sourceLine = 0); +Cookie IODECL(BeginInternalFormattedOutput)(char *internal, + std::size_t internalLength, const char *format, std::size_t formatLength, + const Descriptor *formatDescriptor = nullptr, void **scratchArea = nullptr, + std::size_t scratchBytes = 0, const char *sourceFile = nullptr, + int sourceLine = 0); +Cookie IODECL(BeginInternalFormattedInput)(const char *internal, + std::size_t internalLength, const char *format, std::size_t formatLength, + const Descriptor *formatDescriptor = nullptr, void **scratchArea = nullptr, + std::size_t scratchBytes = 0, const char *sourceFile = nullptr, + int sourceLine = 0); + +// External unit numbers must fit in default integers. When the integer +// provided as UNIT is of a wider type than the default integer, it could +// overflow when converted to a default integer. +// CheckUnitNumberInRange should be called to verify that a unit number of a +// wide integer type can fit in a default integer. Since it should be called +// before the BeginXXX(unit, ...) call, it has its own error handling interface. +// If handleError is false, and the unit number is out of range, the program +// will be terminated. Otherwise, if unit is out of range, a nonzero Iostat +// code is returned and ioMsg is set if it is not a nullptr. +enum Iostat IODECL(CheckUnitNumberInRange64)(std::int64_t unit, + bool handleError, char *ioMsg = nullptr, std::size_t ioMsgLength = 0, + const char *sourceFile = nullptr, int sourceLine = 0); +enum Iostat IODECL(CheckUnitNumberInRange128)(common::int128_t unit, + bool handleError, char *ioMsg = nullptr, std::size_t ioMsgLength = 0, + const char *sourceFile = nullptr, int sourceLine = 0); + +// External synchronous I/O initiation +Cookie IODECL(BeginExternalListOutput)(ExternalUnit = DefaultOutputUnit, + const char *sourceFile = nullptr, int sourceLine = 0); +Cookie IODECL(BeginExternalListInput)(ExternalUnit = DefaultInputUnit, + const char *sourceFile = nullptr, int sourceLine = 0); +Cookie IODECL(BeginExternalFormattedOutput)(const char *format, std::size_t, + const Descriptor *formatDescriptor = nullptr, + ExternalUnit = DefaultOutputUnit, const char *sourceFile = nullptr, + int sourceLine = 0); +Cookie IODECL(BeginExternalFormattedInput)(const char *format, std::size_t, + const Descriptor *formatDescriptor = nullptr, + ExternalUnit = DefaultInputUnit, const char *sourceFile = nullptr, + int sourceLine = 0); +Cookie IODECL(BeginUnformattedOutput)(ExternalUnit = DefaultOutputUnit, + const char *sourceFile = nullptr, int sourceLine = 0); +Cookie IODECL(BeginUnformattedInput)(ExternalUnit = DefaultInputUnit, + const char *sourceFile = nullptr, int sourceLine = 0); + +// WAIT(ID=) +Cookie IODECL(BeginWait)(ExternalUnit, AsynchronousId, + const char *sourceFile = nullptr, int sourceLine = 0); +// WAIT(no ID=) +Cookie IODECL(BeginWaitAll)( + ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); + +// Other I/O statements +Cookie IODECL(BeginClose)( + ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); +Cookie IODECL(BeginFlush)( + ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); +Cookie IODECL(BeginBackspace)( + ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); +Cookie IODECL(BeginEndfile)( + ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); +Cookie IODECL(BeginRewind)( + ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); + +// OPEN(UNIT=) and OPEN(NEWUNIT=) have distinct interfaces. +Cookie IODECL(BeginOpenUnit)( + ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); +Cookie IODECL(BeginOpenNewUnit)( + const char *sourceFile = nullptr, int sourceLine = 0); + +// The variant forms of INQUIRE() statements have distinct interfaces. +// BeginInquireIoLength() is basically a no-op output statement. +Cookie IODECL(BeginInquireUnit)( + ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); +Cookie IODECL(BeginInquireFile)(const char *, std::size_t, + const char *sourceFile = nullptr, int sourceLine = 0); +Cookie IODECL(BeginInquireIoLength)( + const char *sourceFile = nullptr, int sourceLine = 0); + +// If an I/O statement has any IOSTAT=, ERR=, END=, or EOR= specifiers, +// call EnableHandlers() immediately after the Begin...() call. +// An output or OPEN statement may not enable HasEnd or HasEor. +// This call makes the runtime library defer those particular error/end +// conditions to the EndIoStatement() call rather than terminating +// the image. E.g., for READ(*,*,END=666) A, B, (C(J),J=1,N) +// Cookie cookie{BeginExternalListInput(DefaultInputUnit,__FILE__,__LINE__)}; +// EnableHandlers(cookie, false, false, true /*END=*/, false); +// if (InputReal64(cookie, &A)) { +// if (InputReal64(cookie, &B)) { +// for (int J{1}; J<=N; ++J) { +// if (!InputReal64(cookie, &C[J])) break; +// } +// } +// } +// if (EndIoStatement(cookie) == FORTRAN_RUTIME_IOSTAT_END) goto label666; +void IODECL(EnableHandlers)(Cookie, bool hasIoStat = false, bool hasErr = false, + bool hasEnd = false, bool hasEor = false, bool hasIoMsg = false); + +// ASYNCHRONOUS='YES' or 'NO' on READ/WRITE/OPEN +// Use GetAsynchronousId() to handle ID=. +bool IODECL(SetAsynchronous)(Cookie, const char *, std::size_t); + +// Control list options. These return false on a error that the +// Begin...() call has specified will be handled by the caller. +// The interfaces that pass a default-kind CHARACTER argument +// are limited to passing specific case-insensitive keyword values. +// ADVANCE=YES, NO +bool IODECL(SetAdvance)(Cookie, const char *, std::size_t); +// BLANK=NULL, ZERO +bool IODECL(SetBlank)(Cookie, const char *, std::size_t); +// DECIMAL=COMMA, POINT +bool IODECL(SetDecimal)(Cookie, const char *, std::size_t); +// DELIM=APOSTROPHE, QUOTE, NONE +bool IODECL(SetDelim)(Cookie, const char *, std::size_t); +// PAD=YES, NO +bool IODECL(SetPad)(Cookie, const char *, std::size_t); +bool IODECL(SetPos)(Cookie, std::int64_t); +bool IODECL(SetRec)(Cookie, std::int64_t); +// ROUND=UP, DOWN, ZERO, NEAREST, COMPATIBLE, PROCESSOR_DEFINED +bool IODECL(SetRound)(Cookie, const char *, std::size_t); +// SIGN=PLUS, SUPPRESS, PROCESSOR_DEFINED +bool IODECL(SetSign)(Cookie, const char *, std::size_t); + +// Data item transfer for modes other than NAMELIST: +// Any data object that can be passed as an actual argument without the +// use of a temporary can be transferred by means of a descriptor; +// vector-valued subscripts and coindexing will require elementwise +// transfers &/or data copies. Unformatted transfers to/from contiguous +// blocks of local image memory can avoid the descriptor, and there +// are specializations for the most common scalar types. +// +// These functions return false when the I/O statement has encountered an +// error or end-of-file/record condition that the caller has indicated +// should not cause termination of the image by the runtime library. +// Once the statement has encountered an error, all following items will be +// ignored and also return false; but compiled code should check for errors +// and avoid the following items when they might crash. +bool IODECL(OutputDescriptor)(Cookie, const Descriptor &); +bool IODECL(InputDescriptor)(Cookie, const Descriptor &); +// Formatted (including list directed) I/O data items +bool IODECL(OutputInteger8)(Cookie, std::int8_t); +bool IODECL(OutputInteger16)(Cookie, std::int16_t); +bool IODECL(OutputInteger32)(Cookie, std::int32_t); +bool IODECL(OutputInteger64)(Cookie, std::int64_t); +bool IODECL(OutputInteger128)(Cookie, common::int128_t); +bool IODECL(InputInteger)(Cookie, std::int64_t &, int kind = 8); +bool IODECL(OutputReal32)(Cookie, float); +bool IODECL(InputReal32)(Cookie, float &); +bool IODECL(OutputReal64)(Cookie, double); +bool IODECL(InputReal64)(Cookie, double &); +bool IODECL(OutputComplex32)(Cookie, float, float); +bool IODECL(InputComplex32)(Cookie, float[2]); +bool IODECL(OutputComplex64)(Cookie, double, double); +bool IODECL(InputComplex64)(Cookie, double[2]); +bool IODECL(OutputCharacter)(Cookie, const char *, std::size_t, int kind = 1); +bool IODECL(OutputAscii)(Cookie, const char *, std::size_t); +bool IODECL(InputCharacter)(Cookie, char *, std::size_t, int kind = 1); +bool IODECL(InputAscii)(Cookie, char *, std::size_t); +bool IODECL(OutputLogical)(Cookie, bool); +bool IODECL(InputLogical)(Cookie, bool &); + +// NAMELIST I/O must be the only data item in an (otherwise) +// list-directed I/O statement. +bool IODECL(OutputNamelist)(Cookie, const NamelistGroup &); +bool IODECL(InputNamelist)(Cookie, const NamelistGroup &); + +// When an I/O list item has a derived type with a specific defined +// I/O subroutine of the appropriate generic kind for the active +// I/O data transfer statement (read/write, formatted/unformatted) +// that pertains to the type or its components, and those subroutines +// are dynamic or neither type-bound nor defined with interfaces +// in the same scope as the derived type (or an IMPORT statement has +// made such a generic interface inaccessible), these data item transfer +// APIs enable the I/O runtime to make the right calls to defined I/O +// subroutines. +bool IODECL(OutputDerivedType)( + Cookie, const Descriptor &, const NonTbpDefinedIoTable *); +bool IODECL(InputDerivedType)( + Cookie, const Descriptor &, const NonTbpDefinedIoTable *); + +// Additional specifier interfaces for the connection-list of +// on OPEN statement (only). SetBlank(), SetDecimal(), +// SetDelim(), GetIoMsg(), SetPad(), SetRound(), SetSign(), +// & SetAsynchronous() are also acceptable for OPEN. +// ACCESS=SEQUENTIAL, DIRECT, STREAM +bool IODECL(SetAccess)(Cookie, const char *, std::size_t); +// ACTION=READ, WRITE, or READWRITE +bool IODECL(SetAction)(Cookie, const char *, std::size_t); +// CARRIAGECONTROL=LIST, FORTRAN, NONE +bool IODECL(SetCarriagecontrol)(Cookie, const char *, std::size_t); +// CONVERT=NATIVE, LITTLE_ENDIAN, BIG_ENDIAN, or SWAP +bool IODECL(SetConvert)(Cookie, const char *, std::size_t); +// ENCODING=UTF-8, DEFAULT +bool IODECL(SetEncoding)(Cookie, const char *, std::size_t); +// FORM=FORMATTED, UNFORMATTED +bool IODECL(SetForm)(Cookie, const char *, std::size_t); +// POSITION=ASIS, REWIND, APPEND +bool IODECL(SetPosition)(Cookie, const char *, std::size_t); +bool IODECL(SetRecl)(Cookie, std::size_t); // RECL= + +// STATUS can be set during an OPEN or CLOSE statement. +// For OPEN: STATUS=OLD, NEW, SCRATCH, REPLACE, UNKNOWN +// For CLOSE: STATUS=KEEP, DELETE +bool IODECL(SetStatus)(Cookie, const char *, std::size_t); + +bool IODECL(SetFile)(Cookie, const char *, std::size_t chars); + +// Acquires the runtime-created unit number for OPEN(NEWUNIT=) +bool IODECL(GetNewUnit)(Cookie, int &, int kind = 4); + +// READ(SIZE=), after all input items +std::size_t IODECL(GetSize)(Cookie); + +// INQUIRE(IOLENGTH=), after all output items +std::size_t IODECL(GetIoLength)(Cookie); + +// GetIoMsg() does not modify its argument unless an error or +// end-of-record/file condition is present. +void IODECL(GetIoMsg)(Cookie, char *, std::size_t); // IOMSG= + +// Defines ID= on READ/WRITE(ASYNCHRONOUS='YES') +AsynchronousId IODECL(GetAsynchronousId)(Cookie); + +// INQUIRE() specifiers are mostly identified by their NUL-terminated +// case-insensitive names. +// ACCESS, ACTION, ASYNCHRONOUS, BLANK, CONVERT, DECIMAL, DELIM, DIRECT, +// ENCODING, FORM, FORMATTED, NAME, PAD, POSITION, READ, READWRITE, ROUND, +// SEQUENTIAL, SIGN, STREAM, UNFORMATTED, WRITE: +bool IODECL(InquireCharacter)(Cookie, InquiryKeywordHash, char *, std::size_t); +// EXIST, NAMED, OPENED, and PENDING (without ID): +bool IODECL(InquireLogical)(Cookie, InquiryKeywordHash, bool &); +// PENDING with ID +bool IODECL(InquirePendingId)(Cookie, AsynchronousId, bool &); +// NEXTREC, NUMBER, POS, RECL, SIZE +bool IODECL(InquireInteger64)( + Cookie, InquiryKeywordHash, std::int64_t &, int kind = 8); + +// This function must be called to end an I/O statement, and its +// cookie value may not be used afterwards unless it is recycled +// by the runtime library to serve a later I/O statement. +// The return value can be used to implement IOSTAT=, ERR=, END=, & EOR=; +// store it into the IOSTAT= variable if there is one, and test +// it to implement the various branches. The error condition +// returned is guaranteed to only be one of the problems that the +// EnableHandlers() call has indicated should be handled in compiled code +// rather than by terminating the image. +enum Iostat IODECL(EndIoStatement)(Cookie); + +} // extern "C" +} // namespace Fortran::runtime::io + +#endif /* FORTRAN_RUNTIME_IO_API_CONSTS_H_ */ diff --git a/flang/include/flang/Runtime/io-api.h b/flang/include/flang/Runtime/io-api.h index 328afc715a3f1..b86c3cecb32c5 100644 --- a/flang/include/flang/Runtime/io-api.h +++ b/flang/include/flang/Runtime/io-api.h @@ -13,7 +13,8 @@ #include "flang/Common/uint128.h" #include "flang/Runtime/entry-names.h" -#include "flang/Runtime/iostat.h" +#include "flang/Runtime/io-api-consts.h" +#include "flang/Runtime/iostat-consts.h" #include "flang/Runtime/magic-numbers.h" #include #include @@ -31,342 +32,8 @@ using Cookie = IoStatementState *; using ExternalUnit = int; using AsynchronousId = int; -static constexpr ExternalUnit DefaultOutputUnit{FORTRAN_DEFAULT_OUTPUT_UNIT}; -static constexpr ExternalUnit DefaultInputUnit{FORTRAN_DEFAULT_INPUT_UNIT}; - -// INQUIRE specifiers are encoded as simple base-26 packings of -// the spellings of their keywords. -using InquiryKeywordHash = std::uint64_t; -constexpr InquiryKeywordHash HashInquiryKeyword(const char *p) { - InquiryKeywordHash hash{1}; - while (char ch{*p++}) { - std::uint64_t letter{0}; - if (ch >= 'a' && ch <= 'z') { - letter = ch - 'a'; - } else { - letter = ch - 'A'; - } - hash = 26 * hash + letter; - } - return hash; -} - RT_API_ATTRS const char *InquiryKeywordHashDecode( char *buffer, std::size_t, InquiryKeywordHash); -extern "C" { - -#define IONAME(name) RTNAME(io##name) - -#ifndef IODECL -#define IODECL(name) RT_API_ATTRS IONAME(name) -#endif - -#ifndef IODEF -#define IODEF(name) RT_API_ATTRS IONAME(name) -#endif - -// These functions initiate data transfer statements (READ, WRITE, PRINT). -// Example: PRINT *, 666 is implemented as the series of calls: -// Cookie cookie{BeginExternalListOutput(DefaultOutputUnit, -// __FILE__, __LINE__)}; -// OutputInteger32(cookie, 666); -// EndIoStatement(cookie); -// Formatted I/O with explicit formats can supply the format as a -// const char * pointer with a length, or with a descriptor. - -// Internal I/O initiation -// Internal I/O can loan the runtime library an optional block of memory -// in which the library can maintain state across the calls that implement -// the internal transfer; use of these blocks can reduce the need for dynamic -// memory allocation &/or thread-local storage. The block must be sufficiently -// aligned to hold a pointer. -constexpr std::size_t RecommendedInternalIoScratchAreaBytes( - int maxFormatParenthesesNestingDepth) { - return 32 + 8 * maxFormatParenthesesNestingDepth; -} - -// For NAMELIST I/O, use the API for the appropriate form of list-directed -// I/O initiation and configuration, then call OutputNamelist/InputNamelist -// below. - -// Internal I/O to/from character arrays &/or non-default-kind character -// requires a descriptor, which is copied. -Cookie IODECL(BeginInternalArrayListOutput)(const Descriptor &, - void **scratchArea = nullptr, std::size_t scratchBytes = 0, - const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IODECL(BeginInternalArrayListInput)(const Descriptor &, - void **scratchArea = nullptr, std::size_t scratchBytes = 0, - const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IODECL(BeginInternalArrayFormattedOutput)(const Descriptor &, - const char *format, std::size_t formatLength, - const Descriptor *formatDescriptor = nullptr, void **scratchArea = nullptr, - std::size_t scratchBytes = 0, const char *sourceFile = nullptr, - int sourceLine = 0); -Cookie IODECL(BeginInternalArrayFormattedInput)(const Descriptor &, - const char *format, std::size_t formatLength, - const Descriptor *formatDescriptor = nullptr, void **scratchArea = nullptr, - std::size_t scratchBytes = 0, const char *sourceFile = nullptr, - int sourceLine = 0); - -// Internal I/O to/from a default-kind character scalar can avoid a -// descriptor. -Cookie IODECL(BeginInternalListOutput)(char *internal, - std::size_t internalLength, void **scratchArea = nullptr, - std::size_t scratchBytes = 0, const char *sourceFile = nullptr, - int sourceLine = 0); -Cookie IODECL(BeginInternalListInput)(const char *internal, - std::size_t internalLength, void **scratchArea = nullptr, - std::size_t scratchBytes = 0, const char *sourceFile = nullptr, - int sourceLine = 0); -Cookie IODECL(BeginInternalFormattedOutput)(char *internal, - std::size_t internalLength, const char *format, std::size_t formatLength, - const Descriptor *formatDescriptor = nullptr, void **scratchArea = nullptr, - std::size_t scratchBytes = 0, const char *sourceFile = nullptr, - int sourceLine = 0); -Cookie IODECL(BeginInternalFormattedInput)(const char *internal, - std::size_t internalLength, const char *format, std::size_t formatLength, - const Descriptor *formatDescriptor = nullptr, void **scratchArea = nullptr, - std::size_t scratchBytes = 0, const char *sourceFile = nullptr, - int sourceLine = 0); - -// External unit numbers must fit in default integers. When the integer -// provided as UNIT is of a wider type than the default integer, it could -// overflow when converted to a default integer. -// CheckUnitNumberInRange should be called to verify that a unit number of a -// wide integer type can fit in a default integer. Since it should be called -// before the BeginXXX(unit, ...) call, it has its own error handling interface. -// If handleError is false, and the unit number is out of range, the program -// will be terminated. Otherwise, if unit is out of range, a nonzero Iostat -// code is returned and ioMsg is set if it is not a nullptr. -enum Iostat IODECL(CheckUnitNumberInRange64)(std::int64_t unit, - bool handleError, char *ioMsg = nullptr, std::size_t ioMsgLength = 0, - const char *sourceFile = nullptr, int sourceLine = 0); -enum Iostat IODECL(CheckUnitNumberInRange128)(common::int128_t unit, - bool handleError, char *ioMsg = nullptr, std::size_t ioMsgLength = 0, - const char *sourceFile = nullptr, int sourceLine = 0); - -// External synchronous I/O initiation -Cookie IODECL(BeginExternalListOutput)(ExternalUnit = DefaultOutputUnit, - const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IODECL(BeginExternalListInput)(ExternalUnit = DefaultInputUnit, - const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IODECL(BeginExternalFormattedOutput)(const char *format, std::size_t, - const Descriptor *formatDescriptor = nullptr, - ExternalUnit = DefaultOutputUnit, const char *sourceFile = nullptr, - int sourceLine = 0); -Cookie IODECL(BeginExternalFormattedInput)(const char *format, std::size_t, - const Descriptor *formatDescriptor = nullptr, - ExternalUnit = DefaultInputUnit, const char *sourceFile = nullptr, - int sourceLine = 0); -Cookie IODECL(BeginUnformattedOutput)(ExternalUnit = DefaultOutputUnit, - const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IODECL(BeginUnformattedInput)(ExternalUnit = DefaultInputUnit, - const char *sourceFile = nullptr, int sourceLine = 0); - -// WAIT(ID=) -Cookie IODECL(BeginWait)(ExternalUnit, AsynchronousId, - const char *sourceFile = nullptr, int sourceLine = 0); -// WAIT(no ID=) -Cookie IODECL(BeginWaitAll)( - ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); - -// Other I/O statements -Cookie IODECL(BeginClose)( - ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IODECL(BeginFlush)( - ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IODECL(BeginBackspace)( - ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IODECL(BeginEndfile)( - ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IODECL(BeginRewind)( - ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); - -// OPEN(UNIT=) and OPEN(NEWUNIT=) have distinct interfaces. -Cookie IODECL(BeginOpenUnit)( - ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IODECL(BeginOpenNewUnit)( - const char *sourceFile = nullptr, int sourceLine = 0); - -// The variant forms of INQUIRE() statements have distinct interfaces. -// BeginInquireIoLength() is basically a no-op output statement. -Cookie IODECL(BeginInquireUnit)( - ExternalUnit, const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IODECL(BeginInquireFile)(const char *, std::size_t, - const char *sourceFile = nullptr, int sourceLine = 0); -Cookie IODECL(BeginInquireIoLength)( - const char *sourceFile = nullptr, int sourceLine = 0); - -// If an I/O statement has any IOSTAT=, ERR=, END=, or EOR= specifiers, -// call EnableHandlers() immediately after the Begin...() call. -// An output or OPEN statement may not enable HasEnd or HasEor. -// This call makes the runtime library defer those particular error/end -// conditions to the EndIoStatement() call rather than terminating -// the image. E.g., for READ(*,*,END=666) A, B, (C(J),J=1,N) -// Cookie cookie{BeginExternalListInput(DefaultInputUnit,__FILE__,__LINE__)}; -// EnableHandlers(cookie, false, false, true /*END=*/, false); -// if (InputReal64(cookie, &A)) { -// if (InputReal64(cookie, &B)) { -// for (int J{1}; J<=N; ++J) { -// if (!InputReal64(cookie, &C[J])) break; -// } -// } -// } -// if (EndIoStatement(cookie) == FORTRAN_RUTIME_IOSTAT_END) goto label666; -void IODECL(EnableHandlers)(Cookie, bool hasIoStat = false, bool hasErr = false, - bool hasEnd = false, bool hasEor = false, bool hasIoMsg = false); - -// ASYNCHRONOUS='YES' or 'NO' on READ/WRITE/OPEN -// Use GetAsynchronousId() to handle ID=. -bool IODECL(SetAsynchronous)(Cookie, const char *, std::size_t); - -// Control list options. These return false on a error that the -// Begin...() call has specified will be handled by the caller. -// The interfaces that pass a default-kind CHARACTER argument -// are limited to passing specific case-insensitive keyword values. -// ADVANCE=YES, NO -bool IODECL(SetAdvance)(Cookie, const char *, std::size_t); -// BLANK=NULL, ZERO -bool IODECL(SetBlank)(Cookie, const char *, std::size_t); -// DECIMAL=COMMA, POINT -bool IODECL(SetDecimal)(Cookie, const char *, std::size_t); -// DELIM=APOSTROPHE, QUOTE, NONE -bool IODECL(SetDelim)(Cookie, const char *, std::size_t); -// PAD=YES, NO -bool IODECL(SetPad)(Cookie, const char *, std::size_t); -bool IODECL(SetPos)(Cookie, std::int64_t); -bool IODECL(SetRec)(Cookie, std::int64_t); -// ROUND=UP, DOWN, ZERO, NEAREST, COMPATIBLE, PROCESSOR_DEFINED -bool IODECL(SetRound)(Cookie, const char *, std::size_t); -// SIGN=PLUS, SUPPRESS, PROCESSOR_DEFINED -bool IODECL(SetSign)(Cookie, const char *, std::size_t); - -// Data item transfer for modes other than NAMELIST: -// Any data object that can be passed as an actual argument without the -// use of a temporary can be transferred by means of a descriptor; -// vector-valued subscripts and coindexing will require elementwise -// transfers &/or data copies. Unformatted transfers to/from contiguous -// blocks of local image memory can avoid the descriptor, and there -// are specializations for the most common scalar types. -// -// These functions return false when the I/O statement has encountered an -// error or end-of-file/record condition that the caller has indicated -// should not cause termination of the image by the runtime library. -// Once the statement has encountered an error, all following items will be -// ignored and also return false; but compiled code should check for errors -// and avoid the following items when they might crash. -bool IODECL(OutputDescriptor)(Cookie, const Descriptor &); -bool IODECL(InputDescriptor)(Cookie, const Descriptor &); -// Formatted (including list directed) I/O data items -bool IODECL(OutputInteger8)(Cookie, std::int8_t); -bool IODECL(OutputInteger16)(Cookie, std::int16_t); -bool IODECL(OutputInteger32)(Cookie, std::int32_t); -bool IODECL(OutputInteger64)(Cookie, std::int64_t); -bool IODECL(OutputInteger128)(Cookie, common::int128_t); -bool IODECL(InputInteger)(Cookie, std::int64_t &, int kind = 8); -bool IODECL(OutputReal32)(Cookie, float); -bool IODECL(InputReal32)(Cookie, float &); -bool IODECL(OutputReal64)(Cookie, double); -bool IODECL(InputReal64)(Cookie, double &); -bool IODECL(OutputComplex32)(Cookie, float, float); -bool IODECL(InputComplex32)(Cookie, float[2]); -bool IODECL(OutputComplex64)(Cookie, double, double); -bool IODECL(InputComplex64)(Cookie, double[2]); -bool IODECL(OutputCharacter)(Cookie, const char *, std::size_t, int kind = 1); -bool IODECL(OutputAscii)(Cookie, const char *, std::size_t); -bool IODECL(InputCharacter)(Cookie, char *, std::size_t, int kind = 1); -bool IODECL(InputAscii)(Cookie, char *, std::size_t); -bool IODECL(OutputLogical)(Cookie, bool); -bool IODECL(InputLogical)(Cookie, bool &); - -// NAMELIST I/O must be the only data item in an (otherwise) -// list-directed I/O statement. -bool IODECL(OutputNamelist)(Cookie, const NamelistGroup &); -bool IODECL(InputNamelist)(Cookie, const NamelistGroup &); - -// When an I/O list item has a derived type with a specific defined -// I/O subroutine of the appropriate generic kind for the active -// I/O data transfer statement (read/write, formatted/unformatted) -// that pertains to the type or its components, and those subroutines -// are dynamic or neither type-bound nor defined with interfaces -// in the same scope as the derived type (or an IMPORT statement has -// made such a generic interface inaccessible), these data item transfer -// APIs enable the I/O runtime to make the right calls to defined I/O -// subroutines. -bool IODECL(OutputDerivedType)( - Cookie, const Descriptor &, const NonTbpDefinedIoTable *); -bool IODECL(InputDerivedType)( - Cookie, const Descriptor &, const NonTbpDefinedIoTable *); - -// Additional specifier interfaces for the connection-list of -// on OPEN statement (only). SetBlank(), SetDecimal(), -// SetDelim(), GetIoMsg(), SetPad(), SetRound(), SetSign(), -// & SetAsynchronous() are also acceptable for OPEN. -// ACCESS=SEQUENTIAL, DIRECT, STREAM -bool IODECL(SetAccess)(Cookie, const char *, std::size_t); -// ACTION=READ, WRITE, or READWRITE -bool IODECL(SetAction)(Cookie, const char *, std::size_t); -// CARRIAGECONTROL=LIST, FORTRAN, NONE -bool IODECL(SetCarriagecontrol)(Cookie, const char *, std::size_t); -// CONVERT=NATIVE, LITTLE_ENDIAN, BIG_ENDIAN, or SWAP -bool IODECL(SetConvert)(Cookie, const char *, std::size_t); -// ENCODING=UTF-8, DEFAULT -bool IODECL(SetEncoding)(Cookie, const char *, std::size_t); -// FORM=FORMATTED, UNFORMATTED -bool IODECL(SetForm)(Cookie, const char *, std::size_t); -// POSITION=ASIS, REWIND, APPEND -bool IODECL(SetPosition)(Cookie, const char *, std::size_t); -bool IODECL(SetRecl)(Cookie, std::size_t); // RECL= - -// STATUS can be set during an OPEN or CLOSE statement. -// For OPEN: STATUS=OLD, NEW, SCRATCH, REPLACE, UNKNOWN -// For CLOSE: STATUS=KEEP, DELETE -bool IODECL(SetStatus)(Cookie, const char *, std::size_t); - -bool IODECL(SetFile)(Cookie, const char *, std::size_t chars); - -// Acquires the runtime-created unit number for OPEN(NEWUNIT=) -bool IODECL(GetNewUnit)(Cookie, int &, int kind = 4); - -// READ(SIZE=), after all input items -std::size_t IODECL(GetSize)(Cookie); - -// INQUIRE(IOLENGTH=), after all output items -std::size_t IODECL(GetIoLength)(Cookie); - -// GetIoMsg() does not modify its argument unless an error or -// end-of-record/file condition is present. -void IODECL(GetIoMsg)(Cookie, char *, std::size_t); // IOMSG= - -// Defines ID= on READ/WRITE(ASYNCHRONOUS='YES') -AsynchronousId IODECL(GetAsynchronousId)(Cookie); - -// INQUIRE() specifiers are mostly identified by their NUL-terminated -// case-insensitive names. -// ACCESS, ACTION, ASYNCHRONOUS, BLANK, CONVERT, DECIMAL, DELIM, DIRECT, -// ENCODING, FORM, FORMATTED, NAME, PAD, POSITION, READ, READWRITE, ROUND, -// SEQUENTIAL, SIGN, STREAM, UNFORMATTED, WRITE: -bool IODECL(InquireCharacter)(Cookie, InquiryKeywordHash, char *, std::size_t); -// EXIST, NAMED, OPENED, and PENDING (without ID): -bool IODECL(InquireLogical)(Cookie, InquiryKeywordHash, bool &); -// PENDING with ID -bool IODECL(InquirePendingId)(Cookie, AsynchronousId, bool &); -// NEXTREC, NUMBER, POS, RECL, SIZE -bool IODECL(InquireInteger64)( - Cookie, InquiryKeywordHash, std::int64_t &, int kind = 8); - -// This function must be called to end an I/O statement, and its -// cookie value may not be used afterwards unless it is recycled -// by the runtime library to serve a later I/O statement. -// The return value can be used to implement IOSTAT=, ERR=, END=, & EOR=; -// store it into the IOSTAT= variable if there is one, and test -// it to implement the various branches. The error condition -// returned is guaranteed to only be one of the problems that the -// EnableHandlers() call has indicated should be handled in compiled code -// rather than by terminating the image. -enum Iostat IODECL(EndIoStatement)(Cookie); - -} // extern "C" } // namespace Fortran::runtime::io #endif diff --git a/flang/include/flang/Runtime/iostat-consts.h b/flang/include/flang/Runtime/iostat-consts.h new file mode 100644 index 0000000000000..26bf75f59fa0d --- /dev/null +++ b/flang/include/flang/Runtime/iostat-consts.h @@ -0,0 +1,93 @@ +//===-- include/flang/Runtime/iostat-consts.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_RUNTIME_IOSTAT_CONSTS_H_ +#define FORTRAN_RUNTIME_IOSTAT_CONSTS_H_ + +#include "flang/Common/api-attrs.h" +#include "flang/Runtime/magic-numbers.h" + +namespace Fortran::runtime::io { + +// The value of IOSTAT= is zero when no error, end-of-record, +// or end-of-file condition has arisen; errors are positive values. +// (See 12.11.5 in Fortran 2018 for the complete requirements; +// these constants must match the values of their corresponding +// named constants in the predefined module ISO_FORTRAN_ENV, so +// they're actually defined in another magic-numbers.h header file +// so that they can be included both here and there.) +enum Iostat { + IostatOk = 0, // no error, EOF, or EOR condition + + // These error codes are required by Fortran (see 12.10.2.16-17) to be + // negative integer values + IostatEnd = FORTRAN_RUNTIME_IOSTAT_END, // end-of-file on input & no error + // End-of-record on non-advancing input, no EOF or error + IostatEor = FORTRAN_RUNTIME_IOSTAT_EOR, + + // This value is also required to be negative (12.11.5 bullet 6). + // It signifies a FLUSH statement on an unflushable unit. + IostatUnflushable = FORTRAN_RUNTIME_IOSTAT_FLUSH, + + // Other errors are positive. We use "errno" values unchanged. + // This error is exported in ISO_Fortran_env. + IostatInquireInternalUnit = FORTRAN_RUNTIME_IOSTAT_INQUIRE_INTERNAL_UNIT, + + // The remaining error codes are not exported. + IostatGenericError = 1001, // see IOMSG= for details + IostatRecordWriteOverrun, + IostatRecordReadOverrun, + IostatInternalWriteOverrun, + IostatErrorInFormat, + IostatErrorInKeyword, + IostatEndfileDirect, + IostatEndfileUnwritable, + IostatOpenBadRecl, + IostatOpenUnknownSize, + IostatOpenBadAppend, + IostatWriteToReadOnly, + IostatReadFromWriteOnly, + IostatBackspaceNonSequential, + IostatBackspaceAtFirstRecord, + IostatRewindNonSequential, + IostatWriteAfterEndfile, + IostatFormattedIoOnUnformattedUnit, + IostatUnformattedIoOnFormattedUnit, + IostatListIoOnDirectAccessUnit, + IostatUnformattedChildOnFormattedParent, + IostatFormattedChildOnUnformattedParent, + IostatChildInputFromOutputParent, + IostatChildOutputToInputParent, + IostatShortRead, + IostatMissingTerminator, + IostatBadUnformattedRecord, + IostatUTF8Decoding, + IostatUnitOverflow, + IostatBadRealInput, + IostatBadScaleFactor, + IostatBadAsynchronous, + IostatBadWaitUnit, + IostatBOZInputOverflow, + IostatIntegerInputOverflow, + IostatRealInputOverflow, + IostatOpenAlreadyConnected, + IostatCannotReposition, + IostatBadWaitId, + IostatTooManyAsyncOps, + IostatBadBackspaceUnit, + IostatBadUnitNumber, + IostatBadFlushUnit, + IostatBadOpOnChildUnit, + IostatBadNewUnit, + IostatBadListDirectedInputSeparator, + IostatNonExternalDefinedUnformattedIo, +}; + +} // namespace Fortran::runtime::io + +#endif // FORTRAN_RUNTIME_IOSTAT_CONSTS_H_ diff --git a/flang/include/flang/Runtime/iostat.h b/flang/include/flang/Runtime/iostat.h index 6ce7c82b424eb..d8db68a3a1c2e 100644 --- a/flang/include/flang/Runtime/iostat.h +++ b/flang/include/flang/Runtime/iostat.h @@ -11,83 +11,11 @@ #ifndef FORTRAN_RUNTIME_IOSTAT_H_ #define FORTRAN_RUNTIME_IOSTAT_H_ -#include "flang/Common/api-attrs.h" -#include "flang/Runtime/magic-numbers.h" -namespace Fortran::runtime::io { - -// The value of IOSTAT= is zero when no error, end-of-record, -// or end-of-file condition has arisen; errors are positive values. -// (See 12.11.5 in Fortran 2018 for the complete requirements; -// these constants must match the values of their corresponding -// named constants in the predefined module ISO_FORTRAN_ENV, so -// they're actually defined in another magic-numbers.h header file -// so that they can be included both here and there.) -enum Iostat { - IostatOk = 0, // no error, EOF, or EOR condition - - // These error codes are required by Fortran (see 12.10.2.16-17) to be - // negative integer values - IostatEnd = FORTRAN_RUNTIME_IOSTAT_END, // end-of-file on input & no error - // End-of-record on non-advancing input, no EOF or error - IostatEor = FORTRAN_RUNTIME_IOSTAT_EOR, - // This value is also required to be negative (12.11.5 bullet 6). - // It signifies a FLUSH statement on an unflushable unit. - IostatUnflushable = FORTRAN_RUNTIME_IOSTAT_FLUSH, - - // Other errors are positive. We use "errno" values unchanged. - // This error is exported in ISO_Fortran_env. - IostatInquireInternalUnit = FORTRAN_RUNTIME_IOSTAT_INQUIRE_INTERNAL_UNIT, +#include "flang/Common/api-attrs.h" +#include "flang/Runtime/iostat-consts.h" - // The remaining error codes are not exported. - IostatGenericError = 1001, // see IOMSG= for details - IostatRecordWriteOverrun, - IostatRecordReadOverrun, - IostatInternalWriteOverrun, - IostatErrorInFormat, - IostatErrorInKeyword, - IostatEndfileDirect, - IostatEndfileUnwritable, - IostatOpenBadRecl, - IostatOpenUnknownSize, - IostatOpenBadAppend, - IostatWriteToReadOnly, - IostatReadFromWriteOnly, - IostatBackspaceNonSequential, - IostatBackspaceAtFirstRecord, - IostatRewindNonSequential, - IostatWriteAfterEndfile, - IostatFormattedIoOnUnformattedUnit, - IostatUnformattedIoOnFormattedUnit, - IostatListIoOnDirectAccessUnit, - IostatUnformattedChildOnFormattedParent, - IostatFormattedChildOnUnformattedParent, - IostatChildInputFromOutputParent, - IostatChildOutputToInputParent, - IostatShortRead, - IostatMissingTerminator, - IostatBadUnformattedRecord, - IostatUTF8Decoding, - IostatUnitOverflow, - IostatBadRealInput, - IostatBadScaleFactor, - IostatBadAsynchronous, - IostatBadWaitUnit, - IostatBOZInputOverflow, - IostatIntegerInputOverflow, - IostatRealInputOverflow, - IostatOpenAlreadyConnected, - IostatCannotReposition, - IostatBadWaitId, - IostatTooManyAsyncOps, - IostatBadBackspaceUnit, - IostatBadUnitNumber, - IostatBadFlushUnit, - IostatBadOpOnChildUnit, - IostatBadNewUnit, - IostatBadListDirectedInputSeparator, - IostatNonExternalDefinedUnformattedIo, -}; +namespace Fortran::runtime::io { RT_API_ATTRS const char *IostatErrorString(int); diff --git a/flang/include/flang/Runtime/stop.h b/flang/include/flang/Runtime/stop.h index f7c4ffe7403e8..24ae2cbe01ec6 100644 --- a/flang/include/flang/Runtime/stop.h +++ b/flang/include/flang/Runtime/stop.h @@ -11,6 +11,7 @@ #include "flang/Runtime/c-or-cpp.h" #include "flang/Runtime/entry-names.h" +#include "flang/Runtime/extensions.h" #include FORTRAN_EXTERN_C_BEGIN @@ -29,6 +30,7 @@ NORETURN void RTNAME(ProgramEndStatement)(NO_ARGUMENTS); // Extensions NORETURN void RTNAME(Exit)(int status DEFAULT_VALUE(EXIT_SUCCESS)); NORETURN void RTNAME(Abort)(NO_ARGUMENTS); +void FORTRAN_PROCEDURE_NAME(backtrace)(NO_ARGUMENTS); // Crash with an error message when the program dynamically violates a Fortran // constraint. diff --git a/flang/include/flang/Semantics/openmp-modifiers.h b/flang/include/flang/Semantics/openmp-modifiers.h index 4025ce112d9ca..5d5c5e97faf41 100644 --- a/flang/include/flang/Semantics/openmp-modifiers.h +++ b/flang/include/flang/Semantics/openmp-modifiers.h @@ -87,6 +87,8 @@ DECLARE_DESCRIPTOR(parser::OmpOrderingModifier); DECLARE_DESCRIPTOR(parser::OmpPrescriptiveness); DECLARE_DESCRIPTOR(parser::OmpReductionIdentifier); DECLARE_DESCRIPTOR(parser::OmpReductionModifier); +DECLARE_DESCRIPTOR(parser::OmpStepComplexModifier); +DECLARE_DESCRIPTOR(parser::OmpStepSimpleModifier); DECLARE_DESCRIPTOR(parser::OmpTaskDependenceType); DECLARE_DESCRIPTOR(parser::OmpVariableCategory); diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index f97bfec6aaa0e..3aa8b81732561 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -122,7 +122,7 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { bool NoSignedZerosFPMath = false; ///< Set no-signed-zeros-fp-math attribute for functions. bool UnsafeFPMath = false; ///< Set unsafe-fp-math attribute for functions. - bool NSWOnLoopVarInc = false; ///< Add nsw flag to loop variable increments. + bool NSWOnLoopVarInc = true; ///< Add nsw flag to loop variable increments. bool EnableOpenMP = false; ///< Enable OpenMP lowering. }; diff --git a/flang/lib/Evaluate/tools.cpp b/flang/lib/Evaluate/tools.cpp index a040f7ce79dc1..cb6c821433b52 100644 --- a/flang/lib/Evaluate/tools.cpp +++ b/flang/lib/Evaluate/tools.cpp @@ -1719,7 +1719,8 @@ bool IsSaved(const Symbol &original) { return false; } else if (scopeKind == Scope::Kind::Module || (scopeKind == Scope::Kind::MainProgram && - (symbol.attrs().test(Attr::TARGET) || evaluate::IsCoarray(symbol)))) { + (symbol.attrs().test(Attr::TARGET) || evaluate::IsCoarray(symbol)) && + Fortran::evaluate::CanCUDASymbolHaveSaveAttr(symbol))) { // 8.5.16p4 // In main programs, implied SAVE matters only for pointer // initialization targets and coarrays. diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 0a25a9982dfb6..3d4dd67c524e1 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -1395,12 +1395,6 @@ bool CompilerInvocation::createFromArgs( invoc.loweringOpts.setNoPPCNativeVecElemOrder(true); } - // -flang-experimental-integer-overflow - if (args.hasArg( - clang::driver::options::OPT_flang_experimental_integer_overflow)) { - invoc.loweringOpts.setNSWOnLoopVarInc(true); - } - // Preserve all the remark options requested, i.e. -Rpass, -Rpass-missed or // -Rpass-analysis. This will be used later when processing and outputting the // remarks generated by LLVM in ExecuteCompilerInvocation.cpp. diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 9cdc7ee038394..b2eb658422c32 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -858,8 +858,8 @@ void CodeGenAction::generateLLVMIR() { Fortran::common::LanguageFeature::OpenMP)) config.EnableOpenMP = true; - if (ci.getInvocation().getLoweringOpts().getNSWOnLoopVarInc()) - config.NSWOnLoopVarInc = true; + if (ci.getInvocation().getLoweringOpts().getIntegerWrapAround()) + config.NSWOnLoopVarInc = false; // Create the pass pipeline fir::createMLIRToLLVMPassPipeline(pm, config, getCurrentFile()); diff --git a/flang/lib/Lower/Allocatable.cpp b/flang/lib/Lower/Allocatable.cpp index f1436564aabaa..fb8380ac7e8c5 100644 --- a/flang/lib/Lower/Allocatable.cpp +++ b/flang/lib/Lower/Allocatable.cpp @@ -184,14 +184,9 @@ static mlir::Value genRuntimeAllocate(fir::FirOpBuilder &builder, ? fir::runtime::getRuntimeFunc(loc, builder) : fir::runtime::getRuntimeFunc(loc, builder); - llvm::SmallVector args{box.getAddr()}; - if (!box.isPointer()) - args.push_back( - builder.createIntegerConstant(loc, builder.getI64Type(), -1)); - args.push_back(errorManager.hasStat); - args.push_back(errorManager.errMsgAddr); - args.push_back(errorManager.sourceFile); - args.push_back(errorManager.sourceLine); + llvm::SmallVector args{ + box.getAddr(), errorManager.hasStat, errorManager.errMsgAddr, + errorManager.sourceFile, errorManager.sourceLine}; llvm::SmallVector operands; for (auto [fst, snd] : llvm::zip(args, callee.getFunctionType().getInputs())) operands.emplace_back(builder.createConvert(loc, snd, fst)); diff --git a/flang/lib/Lower/Bridge.cpp b/flang/lib/Lower/Bridge.cpp index f518599125e89..de2b941b688be 100644 --- a/flang/lib/Lower/Bridge.cpp +++ b/flang/lib/Lower/Bridge.cpp @@ -56,7 +56,7 @@ #include "flang/Optimizer/Support/InternalNames.h" #include "flang/Optimizer/Transforms/Passes.h" #include "flang/Parser/parse-tree.h" -#include "flang/Runtime/iostat.h" +#include "flang/Runtime/iostat-consts.h" #include "flang/Semantics/runtime-type-info.h" #include "flang/Semantics/symbol.h" #include "flang/Semantics/tools.h" @@ -711,8 +711,8 @@ class FirConverter : public Fortran::lower::AbstractConverter { return bool(shallowLookupSymbol(sym)); } - bool createHostAssociateVarClone( - const Fortran::semantics::Symbol &sym) override final { + bool createHostAssociateVarClone(const Fortran::semantics::Symbol &sym, + bool skipDefaultInit) override final { mlir::Location loc = genLocation(sym.name()); mlir::Type symType = genType(sym); const auto *details = sym.detailsIf(); @@ -769,13 +769,21 @@ class FirConverter : public Fortran::lower::AbstractConverter { // Initialise cloned allocatable hexv.match( [&](const fir::MutableBoxValue &box) -> void { - // Do not process pointers + const auto new_box = exv.getBoxOf(); if (Fortran::semantics::IsPointer(sym.GetUltimate())) { + // Establish the pointer descriptors. The rank and type code/size + // at least must be set properly for later inquiry of the pointer + // to work, and new pointers are always given disassociated status + // by flang for safety, even if this is not required by the + // language. + auto empty = fir::factory::createUnallocatedBox( + *builder, loc, new_box->getBoxTy(), box.nonDeferredLenParams(), + {}); + builder->create(loc, empty, new_box->getAddr()); return; } - // Allocate storage for a pointer/allocatble descriptor. - // No shape/lengths to be passed to the alloca. - const auto new_box = exv.getBoxOf(); + // Copy allocation status of Allocatables, creating new storage if + // needed. // allocate if allocated mlir::Value isAllocated = @@ -823,7 +831,22 @@ class FirConverter : public Fortran::lower::AbstractConverter { if_builder.end(); }, [&](const auto &) -> void { - // Do nothing + if (skipDefaultInit) + return; + // Initialize local/private derived types with default + // initialization (Fortran 2023 section 11.1.7.5 and OpenMP 5.2 + // section 5.3). Pointer and allocatable components, when allowed, + // also need to be established so that flang runtime can later work + // with them. + if (const Fortran::semantics::DeclTypeSpec *declTypeSpec = + sym.GetType()) + if (const Fortran::semantics::DerivedTypeSpec *derivedTypeSpec = + declTypeSpec->AsDerived()) + if (derivedTypeSpec->HasDefaultInitialization( + /*ignoreAllocatable=*/false, /*ignorePointer=*/false)) { + mlir::Value box = builder->createBox(loc, exv); + fir::runtime::genDerivedTypeInitialize(*builder, loc, box); + } }); return bindIfNewSymbol(sym, exv); @@ -1966,9 +1989,9 @@ class FirConverter : public Fortran::lower::AbstractConverter { Fortran::semantics::SemanticsContext &semanticsContext = bridge.getSemanticsContext(); for (const Fortran::semantics::Symbol *sym : info.localSymList) - createHostAssociateVarClone(*sym); + createHostAssociateVarClone(*sym, /*skipDefaultInit=*/false); for (const Fortran::semantics::Symbol *sym : info.localInitSymList) { - createHostAssociateVarClone(*sym); + createHostAssociateVarClone(*sym, /*skipDefaultInit=*/true); const auto *hostDetails = sym->detailsIf(); assert(hostDetails && "missing locality spec host symbol"); @@ -1986,6 +2009,9 @@ class FirConverter : public Fortran::lower::AbstractConverter { sym->detailsIf(); copySymbolBinding(hostDetails->symbol(), *sym); } + // Note that allocatable, types with ultimate components, and type + // requiring finalization are forbidden in LOCAL/LOCAL_INIT (F2023 C1130), + // so no clean-up needs to be generated for these entities. } /// Generate FIR for a DO construct. There are six variants: @@ -2304,7 +2330,7 @@ class FirConverter : public Fortran::lower::AbstractConverter { assert(!incrementLoopNestInfo.empty() && "empty loop nest"); mlir::Location loc = toLocation(); mlir::arith::IntegerOverflowFlags flags{}; - if (getLoweringOptions().getNSWOnLoopVarInc()) + if (!getLoweringOptions().getIntegerWrapAround()) flags = bitEnumSet(flags, mlir::arith::IntegerOverflowFlags::nsw); auto iofAttr = mlir::arith::IntegerOverflowFlagsAttr::get( builder->getContext(), flags); @@ -3011,8 +3037,10 @@ class FirConverter : public Fortran::lower::AbstractConverter { fir::getBase(genExprValue(*Fortran::semantics::GetExpr(bounds->upper), stmtCtx)))); if (bounds->step) - steps.push_back(fir::getBase( - genExprValue(*Fortran::semantics::GetExpr(bounds->step), stmtCtx))); + steps.push_back(builder->createConvert( + crtLoc, idxTy, + fir::getBase(genExprValue( + *Fortran::semantics::GetExpr(bounds->step), stmtCtx)))); else // If `step` is not present, assume it is `1`. steps.push_back(builder->createIntegerConstant(loc, idxTy, 1)); diff --git a/flang/lib/Lower/ConvertVariable.cpp b/flang/lib/Lower/ConvertVariable.cpp index 197e526973b4d..ff122c21e37ad 100644 --- a/flang/lib/Lower/ConvertVariable.cpp +++ b/flang/lib/Lower/ConvertVariable.cpp @@ -39,7 +39,7 @@ #include "flang/Optimizer/Support/FatalError.h" #include "flang/Optimizer/Support/InternalNames.h" #include "flang/Optimizer/Support/Utils.h" -#include "flang/Runtime/allocator-registry.h" +#include "flang/Runtime/allocator-registry-consts.h" #include "flang/Semantics/runtime-type-info.h" #include "flang/Semantics/tools.h" #include "llvm/Support/CommandLine.h" diff --git a/flang/lib/Lower/HlfirIntrinsics.cpp b/flang/lib/Lower/HlfirIntrinsics.cpp index 310b62697f710..9d3cd3a5c8fa1 100644 --- a/flang/lib/Lower/HlfirIntrinsics.cpp +++ b/flang/lib/Lower/HlfirIntrinsics.cpp @@ -159,6 +159,17 @@ class HlfirCharExtremumLowering : public HlfirTransformationalIntrinsic { hlfir::CharExtremumPredicate pred; }; +class HlfirCShiftLowering : public HlfirTransformationalIntrinsic { +public: + using HlfirTransformationalIntrinsic::HlfirTransformationalIntrinsic; + +protected: + mlir::Value + lowerImpl(const Fortran::lower::PreparedActualArguments &loweredActuals, + const fir::IntrinsicArgumentLoweringRules *argLowering, + mlir::Type stmtResultType) override; +}; + } // namespace mlir::Value HlfirTransformationalIntrinsic::loadBoxAddress( @@ -270,11 +281,12 @@ HlfirTransformationalIntrinsic::computeResultType(mlir::Value argArray, hlfir::ExprType::Shape{array.getShape()}; mlir::Type elementType = array.getEleTy(); return hlfir::ExprType::get(builder.getContext(), resultShape, elementType, - /*polymorphic=*/false); + fir::isPolymorphicType(stmtResultType)); } else if (auto resCharType = mlir::dyn_cast(stmtResultType)) { normalisedResult = hlfir::ExprType::get( - builder.getContext(), hlfir::ExprType::Shape{}, resCharType, false); + builder.getContext(), hlfir::ExprType::Shape{}, resCharType, + /*polymorphic=*/false); } return normalisedResult; } @@ -387,6 +399,26 @@ mlir::Value HlfirCharExtremumLowering::lowerImpl( return createOp(pred, mlir::ValueRange{operands}); } +mlir::Value HlfirCShiftLowering::lowerImpl( + const Fortran::lower::PreparedActualArguments &loweredActuals, + const fir::IntrinsicArgumentLoweringRules *argLowering, + mlir::Type stmtResultType) { + auto operands = getOperandVector(loweredActuals, argLowering); + assert(operands.size() == 3); + mlir::Value dim = operands[2]; + if (!dim) { + // If DIM is not present, drop the last element which is a null Value. + operands.truncate(2); + } else { + // If DIM is present, then dereference it if it is a ref. + dim = hlfir::loadTrivialScalar(loc, builder, hlfir::Entity{dim}); + operands[2] = dim; + } + + mlir::Type resultType = computeResultType(operands[0], stmtResultType); + return createOp(resultType, operands); +} + std::optional Fortran::lower::lowerHlfirIntrinsic( fir::FirOpBuilder &builder, mlir::Location loc, const std::string &name, const Fortran::lower::PreparedActualArguments &loweredActuals, @@ -432,6 +464,9 @@ std::optional Fortran::lower::lowerHlfirIntrinsic( if (name == "maxloc") return HlfirMaxlocLowering{builder, loc}.lower(loweredActuals, argLowering, stmtResultType); + if (name == "cshift") + return HlfirCShiftLowering{builder, loc}.lower(loweredActuals, argLowering, + stmtResultType); if (mlir::isa(stmtResultType)) { if (name == "min") return HlfirCharExtremumLowering{builder, loc, diff --git a/flang/lib/Lower/IO.cpp b/flang/lib/Lower/IO.cpp index 1894b0cfd1bec..89e0aa2228655 100644 --- a/flang/lib/Lower/IO.cpp +++ b/flang/lib/Lower/IO.cpp @@ -33,7 +33,7 @@ #include "flang/Optimizer/Dialect/FIRDialect.h" #include "flang/Optimizer/Dialect/Support/FIRContext.h" #include "flang/Parser/parse-tree.h" -#include "flang/Runtime/io-api.h" +#include "flang/Runtime/io-api-consts.h" #include "flang/Semantics/runtime-type-info.h" #include "flang/Semantics/tools.h" #include "mlir/Dialect/ControlFlow/IR/ControlFlowOps.h" @@ -929,7 +929,7 @@ static void genIoLoop(Fortran::lower::AbstractConverter &converter, fir::FirOpBuilder &builder = converter.getFirOpBuilder(); mlir::Location loc = converter.getCurrentLocation(); mlir::arith::IntegerOverflowFlags flags{}; - if (converter.getLoweringOptions().getNSWOnLoopVarInc()) + if (!converter.getLoweringOptions().getIntegerWrapAround()) flags = bitEnumSet(flags, mlir::arith::IntegerOverflowFlags::nsw); auto iofAttr = mlir::arith::IntegerOverflowFlagsAttr::get(builder.getContext(), flags); diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp index 878dccc4ecbc4..75dcf6ec3e110 100644 --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -139,6 +139,8 @@ createDataEntryOp(fir::FirOpBuilder &builder, mlir::Location loc, op.setStructured(structured); op.setImplicit(implicit); op.setDataClause(dataClause); + op.setVarType(mlir::cast(baseAddr.getType()) + .getElementType()); op->setAttr(Op::getOperandSegmentSizeAttr(), builder.getDenseI32ArrayAttr(operandSegments)); if (!asyncDeviceTypes.empty()) @@ -266,8 +268,8 @@ static void createDeclareDeallocFuncWithArg( if constexpr (std::is_same_v || std::is_same_v) builder.create(entryOp.getLoc(), entryOp.getAccPtr(), - entryOp.getVarPtr(), entryOp.getBounds(), - entryOp.getAsyncOperands(), + entryOp.getVarPtr(), entryOp.getVarType(), + entryOp.getBounds(), entryOp.getAsyncOperands(), entryOp.getAsyncOperandsDeviceTypeAttr(), entryOp.getAsyncOnlyAttr(), entryOp.getDataClause(), /*structured=*/false, /*implicit=*/false, @@ -450,7 +452,7 @@ static void genDataExitOperations(fir::FirOpBuilder &builder, std::is_same_v) builder.create( entryOp.getLoc(), entryOp.getAccPtr(), entryOp.getVarPtr(), - entryOp.getBounds(), entryOp.getAsyncOperands(), + entryOp.getVarType(), entryOp.getBounds(), entryOp.getAsyncOperands(), entryOp.getAsyncOperandsDeviceTypeAttr(), entryOp.getAsyncOnlyAttr(), entryOp.getDataClause(), structured, entryOp.getImplicit(), builder.getStringAttr(*entryOp.getName())); diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp index 03aaf7e12a4dd..0f8ec040a9cf8 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.cpp +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.cpp @@ -220,6 +220,10 @@ static void convertLoopBounds(lower::AbstractConverter &converter, // ClauseProcessor unique clauses //===----------------------------------------------------------------------===// +bool ClauseProcessor::processBare(mlir::omp::BareClauseOps &result) const { + return markClauseOccurrence(result.bare); +} + bool ClauseProcessor::processBind(mlir::omp::BindClauseOps &result) const { if (auto *clause = findUniqueClause()) { fir::FirOpBuilder &firOpBuilder = converter.getFirOpBuilder(); @@ -458,6 +462,16 @@ bool ClauseProcessor::processPriority( return false; } +bool ClauseProcessor::processDetach(mlir::omp::DetachClauseOps &result) const { + if (auto *clause = findUniqueClause()) { + semantics::Symbol *sym = clause->v.sym(); + mlir::Value symVal = converter.getSymbolAddress(*sym); + result.eventHandle = symVal; + return true; + } + return false; +} + bool ClauseProcessor::processProcBind( mlir::omp::ProcBindClauseOps &result) const { if (auto *clause = findUniqueClause()) { diff --git a/flang/lib/Lower/OpenMP/ClauseProcessor.h b/flang/lib/Lower/OpenMP/ClauseProcessor.h index ea3bf13000ded..2a559eaab80d9 100644 --- a/flang/lib/Lower/OpenMP/ClauseProcessor.h +++ b/flang/lib/Lower/OpenMP/ClauseProcessor.h @@ -53,6 +53,7 @@ class ClauseProcessor { : converter(converter), semaCtx(semaCtx), clauses(clauses) {} // 'Unique' clauses: They can appear at most once in the clause list. + bool processBare(mlir::omp::BareClauseOps &result) const; bool processBind(mlir::omp::BindClauseOps &result) const; bool processCollapse(mlir::Location currentLocation, lower::pft::Evaluation &eval, @@ -90,6 +91,7 @@ class ClauseProcessor { mlir::omp::ThreadLimitClauseOps &result) const; bool processUntied(mlir::omp::UntiedClauseOps &result) const; + bool processDetach(mlir::omp::DetachClauseOps &result) const; // 'Repeatable' clauses: They can appear multiple times in the clause list. bool processAligned(mlir::omp::AlignedClauseOps &result) const; bool processAllocate(mlir::omp::AllocateClauseOps &result) const; diff --git a/flang/lib/Lower/OpenMP/Clauses.cpp b/flang/lib/Lower/OpenMP/Clauses.cpp index 6b730d5693588..319a73bb2539a 100644 --- a/flang/lib/Lower/OpenMP/Clauses.cpp +++ b/flang/lib/Lower/OpenMP/Clauses.cpp @@ -859,10 +859,14 @@ Init make(const parser::OmpClause::Init &inp, InReduction make(const parser::OmpClause::InReduction &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpInReductionClause - auto &t0 = std::get(inp.v.t); + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *m0 = + semantics::OmpGetUniqueModifier(mods); auto &t1 = std::get(inp.v.t); + assert(m0 && "OmpReductionIdentifier is required"); + return InReduction{ - {/*ReductionIdentifiers=*/{makeReductionOperator(t0, semaCtx)}, + {/*ReductionIdentifiers=*/{makeReductionOperator(*m0, semaCtx)}, /*List=*/makeObjects(t1, semaCtx)}}; } @@ -895,8 +899,6 @@ Lastprivate make(const parser::OmpClause::Lastprivate &inp, Linear make(const parser::OmpClause::Linear &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpLinearClause - using wrapped = parser::OmpLinearClause; - CLAUSET_ENUM_CONVERT( // convert, parser::OmpLinearModifier::Value, Linear::LinearModifier, // clang-format off @@ -906,26 +908,23 @@ Linear make(const parser::OmpClause::Linear &inp, // clang-format on ); - using Tuple = decltype(Linear::t); + auto &mods = semantics::OmpGetModifiers(inp.v); + auto *m0 = + semantics::OmpGetUniqueModifier(mods); + auto *m1 = + semantics::OmpGetUniqueModifier(mods); + assert((!m0 || !m1) && "Simple and complex modifiers both present"); - return Linear{Fortran::common::visit( - common::visitors{ - [&](const wrapped::WithModifier &s) -> Tuple { - return { - /*StepSimpleModifier=*/std::nullopt, - /*StepComplexModifier=*/maybeApply(makeExprFn(semaCtx), s.step), - /*LinearModifier=*/convert(s.modifier.v), - /*List=*/makeList(s.names, makeObjectFn(semaCtx))}; - }, - [&](const wrapped::WithoutModifier &s) -> Tuple { - return { - /*StepSimpleModifier=*/maybeApply(makeExprFn(semaCtx), s.step), - /*StepComplexModifier=*/std::nullopt, - /*LinearModifier=*/std::nullopt, - /*List=*/makeList(s.names, makeObjectFn(semaCtx))}; - }, - }, - inp.v.u)}; + auto *m2 = semantics::OmpGetUniqueModifier(mods); + auto &t1 = std::get(inp.v.t); + + auto &&maybeStep = m0 ? maybeApplyToV(makeExprFn(semaCtx), m0) + : m1 ? maybeApplyToV(makeExprFn(semaCtx), m1) + : std::optional{}; + + return Linear{{/*StepComplexModifier=*/std::move(maybeStep), + /*LinearModifier=*/maybeApplyToV(convert, m2), + /*List=*/makeObjects(t1, semaCtx)}}; } Link make(const parser::OmpClause::Link &inp, @@ -1155,17 +1154,17 @@ Reduction make(const parser::OmpClause::Reduction &inp, ); auto &mods = semantics::OmpGetModifiers(inp.v); - auto *t0 = + auto *m0 = semantics::OmpGetUniqueModifier(mods); - auto *t1 = + auto *m1 = semantics::OmpGetUniqueModifier(mods); - auto &t2 = std::get(inp.v.t); - assert(t1 && "OmpReductionIdentifier is required"); + auto &t1 = std::get(inp.v.t); + assert(m1 && "OmpReductionIdentifier is required"); return Reduction{ - {/*ReductionModifier=*/maybeApplyToV(convert, t0), - /*ReductionIdentifiers=*/{makeReductionOperator(*t1, semaCtx)}, - /*List=*/makeObjects(t2, semaCtx)}}; + {/*ReductionModifier=*/maybeApplyToV(convert, m0), + /*ReductionIdentifiers=*/{makeReductionOperator(*m1, semaCtx)}, + /*List=*/makeObjects(t1, semaCtx)}}; } // Relaxed: empty @@ -1259,13 +1258,13 @@ TaskReduction make(const parser::OmpClause::TaskReduction &inp, semantics::SemanticsContext &semaCtx) { // inp.v -> parser::OmpReductionClause auto &mods = semantics::OmpGetModifiers(inp.v); - auto *t0 = + auto *m0 = semantics::OmpGetUniqueModifier(mods); auto &t1 = std::get(inp.v.t); - assert(t0 && "OmpReductionIdentifier is required"); + assert(m0 && "OmpReductionIdentifier is required"); return TaskReduction{ - {/*ReductionIdentifiers=*/{makeReductionOperator(*t0, semaCtx)}, + {/*ReductionIdentifiers=*/{makeReductionOperator(*m0, semaCtx)}, /*List=*/makeObjects(t1, semaCtx)}}; } diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp index 43b4d25ff4179..eec48adce3f62 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.cpp @@ -38,7 +38,7 @@ DataSharingProcessor::DataSharingProcessor( lower::AbstractConverter &converter, semantics::SemanticsContext &semaCtx, const List &clauses, lower::pft::Evaluation &eval, bool shouldCollectPreDeterminedSymbols, bool useDelayedPrivatization, - lower::SymMap *symTable) + lower::SymMap &symTable) : converter(converter), semaCtx(semaCtx), firOpBuilder(converter.getFirOpBuilder()), clauses(clauses), eval(eval), shouldCollectPreDeterminedSymbols(shouldCollectPreDeterminedSymbols), @@ -98,7 +98,7 @@ void DataSharingProcessor::insertDeallocs() { fir::ExtendedValue symExV = converter.getSymbolExtendedValue(*sym); mlir::omp::PrivateClauseOp privatizer = symToPrivatizer.at(sym); - lower::SymMapScope scope(*symTable); + lower::SymMapScope scope(symTable); mlir::OpBuilder::InsertionGuard guard(firOpBuilder); mlir::Region &deallocRegion = privatizer.getDeallocRegion(); @@ -107,8 +107,8 @@ void DataSharingProcessor::insertDeallocs() { &deallocRegion, /*insertPt=*/{}, symType, symLoc); firOpBuilder.setInsertionPointToEnd(deallocEntryBlock); - symTable->addSymbol(*sym, - fir::substBase(symExV, deallocRegion.getArgument(0))); + symTable.addSymbol(*sym, + fir::substBase(symExV, deallocRegion.getArgument(0))); converter.createHostAssociateVarCloneDealloc(*sym); firOpBuilder.create(hsb.getAddr().getLoc()); @@ -116,14 +116,11 @@ void DataSharingProcessor::insertDeallocs() { } void DataSharingProcessor::cloneSymbol(const semantics::Symbol *sym) { - bool success = converter.createHostAssociateVarClone(*sym); + bool isFirstPrivate = sym->test(semantics::Symbol::Flag::OmpFirstPrivate); + bool success = converter.createHostAssociateVarClone( + *sym, /*skipDefaultInit=*/isFirstPrivate); (void)success; assert(success && "Privatization failed due to existing binding"); - - bool isFirstPrivate = sym->test(semantics::Symbol::Flag::OmpFirstPrivate); - if (!isFirstPrivate && - Fortran::lower::hasDefaultInitialization(sym->GetUltimate())) - Fortran::lower::defaultInitializeAtRuntime(converter, *sym, *symTable); } void DataSharingProcessor::copyFirstPrivateSymbol( @@ -483,7 +480,7 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym, isFirstPrivate ? mlir::omp::DataSharingClauseType::FirstPrivate : mlir::omp::DataSharingClauseType::Private); fir::ExtendedValue symExV = converter.getSymbolExtendedValue(*sym); - lower::SymMapScope outerScope(*symTable); + lower::SymMapScope outerScope(symTable); // Populate the `alloc` region. { @@ -500,10 +497,10 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym, evaluate::IsSimplyContiguous(*sym, converter.getFoldingContext())) .first; - symTable->addSymbol(*sym, localExV); - lower::SymMapScope innerScope(*symTable); + symTable.addSymbol(*sym, localExV); + lower::SymMapScope innerScope(symTable); cloneSymbol(sym); - mlir::Value cloneAddr = symTable->shallowLookupSymbol(*sym).getAddr(); + mlir::Value cloneAddr = symTable.shallowLookupSymbol(*sym).getAddr(); mlir::Type cloneType = cloneAddr.getType(); // A `convert` op is required for variables that are storage associated @@ -531,25 +528,24 @@ void DataSharingProcessor::doPrivatize(const semantics::Symbol *sym, auto addSymbol = [&](unsigned argIdx, bool force = false) { symExV.match( [&](const fir::MutableBoxValue &box) { - symTable->addSymbol( + symTable.addSymbol( *sym, fir::substBase(box, copyRegion.getArgument(argIdx)), force); }, [&](const auto &box) { - symTable->addSymbol(*sym, copyRegion.getArgument(argIdx), force); + symTable.addSymbol(*sym, copyRegion.getArgument(argIdx), force); }); }; addSymbol(0, true); - lower::SymMapScope innerScope(*symTable); + lower::SymMapScope innerScope(symTable); addSymbol(1); auto ip = firOpBuilder.saveInsertionPoint(); copyFirstPrivateSymbol(sym, &ip); firOpBuilder.create( - hsb.getAddr().getLoc(), - symTable->shallowLookupSymbol(*sym).getAddr()); + hsb.getAddr().getLoc(), symTable.shallowLookupSymbol(*sym).getAddr()); } return result; diff --git a/flang/lib/Lower/OpenMP/DataSharingProcessor.h b/flang/lib/Lower/OpenMP/DataSharingProcessor.h index 695e0e4743f96..780e0b4a030d3 100644 --- a/flang/lib/Lower/OpenMP/DataSharingProcessor.h +++ b/flang/lib/Lower/OpenMP/DataSharingProcessor.h @@ -86,7 +86,7 @@ class DataSharingProcessor { lower::pft::Evaluation &eval; bool shouldCollectPreDeterminedSymbols; bool useDelayedPrivatization; - lower::SymMap *symTable; + lower::SymMap &symTable; OMPConstructSymbolVisitor visitor; bool privatizationDone = false; @@ -124,8 +124,7 @@ class DataSharingProcessor { const List &clauses, lower::pft::Evaluation &eval, bool shouldCollectPreDeterminedSymbols, - bool useDelayedPrivatization = false, - lower::SymMap *symTable = nullptr); + bool useDelayedPrivatization, lower::SymMap &symTable); // Privatisation is split into 3 steps: // diff --git a/flang/lib/Lower/OpenMP/OpenMP.cpp b/flang/lib/Lower/OpenMP/OpenMP.cpp index ccea3265cce44..4cb570c492bb0 100644 --- a/flang/lib/Lower/OpenMP/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP/OpenMP.cpp @@ -381,6 +381,9 @@ extractOmpDirective(const parser::OpenMPConstruct &ompConstruct) { [](const parser::OpenMPDeclarativeAllocate &c) { return llvm::omp::OMPD_allocate; }, + [](const parser::OpenMPErrorConstruct &c) { + return llvm::omp::OMPD_error; + }, [](const parser::OpenMPExecutableAllocate &c) { return llvm::omp::OMPD_allocate; }, @@ -1102,7 +1105,8 @@ static void createBodyOfOp(mlir::Operation &op, const OpWithBodyGenInfo &info, std::optional tempDsp; if (privatize && !info.dsp) { tempDsp.emplace(info.converter, info.semaCtx, *info.clauses, info.eval, - Fortran::lower::omp::isLastItemInQueue(item, queue)); + Fortran::lower::omp::isLastItemInQueue(item, queue), + /*useDelayedPrivatization=*/false, info.symTable); tempDsp->processStep1(); tempDsp->processStep2(); } @@ -1617,6 +1621,7 @@ static void genTargetClauses( llvm::SmallVectorImpl &isDevicePtrSyms, llvm::SmallVectorImpl &mapSyms) { ClauseProcessor cp(converter, semaCtx, clauses); + cp.processBare(clauseOps); cp.processDepend(clauseOps); cp.processDevice(stmtCtx, clauseOps); cp.processHasDeviceAddr(clauseOps, hasDeviceAddrSyms); @@ -1700,8 +1705,10 @@ static void genTaskClauses(lower::AbstractConverter &converter, cp.processMergeable(clauseOps); cp.processPriority(stmtCtx, clauseOps); cp.processUntied(clauseOps); + cp.processDetach(clauseOps); + // TODO Support delayed privatization. - cp.processTODO( + cp.processTODO( loc, llvm::omp::Directive::OMPD_task); } @@ -1865,7 +1872,7 @@ static void genLoopOp(lower::AbstractConverter &converter, DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/true, - /*useDelayedPrivatization=*/true, &symTable); + /*useDelayedPrivatization=*/true, symTable); dsp.processStep1(); dsp.processStep2(&loopClauseOps); @@ -1987,7 +1994,8 @@ genSectionsOp(lower::AbstractConverter &converter, lower::SymMap &symTable, // Insert privatizations before SECTIONS lower::SymMapScope scope(symTable); DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval, - lower::omp::isLastItemInQueue(item, queue)); + lower::omp::isLastItemInQueue(item, queue), + /*useDelayedPrivatization=*/false, symTable); dsp.processStep1(); // TODO: Add support for delayed privatization. dsp.processStep2(); @@ -2142,10 +2150,10 @@ genTargetOp(lower::AbstractConverter &converter, lower::SymMap &symTable, DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/ lower::omp::isLastItemInQueue(item, queue), - enableDelayedPrivatizationStaging, &symTable); + /*useDelayedPrivatization=*/true, symTable); dsp.processStep1(); - if (enableDelayedPrivatizationStaging) - dsp.processStep2(&clauseOps); + dsp.processStep2(&clauseOps); + // 5.8.1 Implicit Data-Mapping Attribute Rules // The following code follows the implicit data-mapping rules to map all the // symbols used inside the region that do not have explicit data-environment @@ -2347,7 +2355,7 @@ genTaskOp(lower::AbstractConverter &converter, lower::SymMap &symTable, DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval, lower::omp::isLastItemInQueue(item, queue), - /*useDelayedPrivatization=*/true, &symTable); + /*useDelayedPrivatization=*/true, symTable); dsp.processStep1(); dsp.processStep2(&clauseOps); @@ -2482,7 +2490,7 @@ static void genStandaloneDistribute(lower::AbstractConverter &converter, DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/true, - enableDelayedPrivatizationStaging, &symTable); + enableDelayedPrivatizationStaging, symTable); dsp.processStep1(); dsp.processStep2(&distributeClauseOps); @@ -2516,7 +2524,7 @@ static void genStandaloneDo(lower::AbstractConverter &converter, DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/true, - enableDelayedPrivatizationStaging, &symTable); + enableDelayedPrivatizationStaging, symTable); dsp.processStep1(); dsp.processStep2(&wsloopClauseOps); @@ -2556,7 +2564,7 @@ static void genStandaloneParallel(lower::AbstractConverter &converter, if (enableDelayedPrivatization) { dsp.emplace(converter, semaCtx, item->clauses, eval, lower::omp::isLastItemInQueue(item, queue), - /*useDelayedPrivatization=*/true, &symTable); + /*useDelayedPrivatization=*/true, symTable); dsp->processStep1(); dsp->processStep2(¶llelClauseOps); } @@ -2587,7 +2595,7 @@ static void genStandaloneSimd(lower::AbstractConverter &converter, // TODO: Support delayed privatization. DataSharingProcessor dsp(converter, semaCtx, item->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/true, - /*useDelayedPrivatization=*/false, &symTable); + /*useDelayedPrivatization=*/false, symTable); dsp.processStep1(); dsp.processStep2(); @@ -2642,7 +2650,7 @@ static void genCompositeDistributeParallelDo( DataSharingProcessor dsp(converter, semaCtx, doItem->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/true, - /*useDelayedPrivatization=*/true, &symTable); + /*useDelayedPrivatization=*/true, symTable); dsp.processStep1(); dsp.processStep2(¶llelClauseOps); @@ -2711,7 +2719,7 @@ static void genCompositeDistributeParallelDoSimd( DataSharingProcessor dsp(converter, semaCtx, simdItem->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/true, - /*useDelayedPrivatization=*/true, &symTable); + /*useDelayedPrivatization=*/true, symTable); dsp.processStep1(); dsp.processStep2(¶llelClauseOps); @@ -2800,7 +2808,7 @@ static void genCompositeDistributeSimd(lower::AbstractConverter &converter, // TODO: Support delayed privatization. DataSharingProcessor dsp(converter, semaCtx, simdItem->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/true, - /*useDelayedPrivatization=*/false, &symTable); + /*useDelayedPrivatization=*/false, symTable); dsp.processStep1(); dsp.processStep2(); @@ -2858,7 +2866,7 @@ static void genCompositeDoSimd(lower::AbstractConverter &converter, // TODO: Support delayed privatization. DataSharingProcessor dsp(converter, semaCtx, simdItem->clauses, eval, /*shouldCollectPreDeterminedSymbols=*/true, - /*useDelayedPrivatization=*/false, &symTable); + /*useDelayedPrivatization=*/false, symTable); dsp.processStep1(); dsp.processStep2(); @@ -3337,6 +3345,7 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && @@ -3349,7 +3358,8 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && !std::holds_alternative(clause.u) && - !std::holds_alternative(clause.u)) { + !std::holds_alternative(clause.u) && + !std::holds_alternative(clause.u)) { std::string name = parser::ToUpperCaseLetters(llvm::omp::getOpenMPClauseName(clause.id)); TODO(clauseLocation, name + " clause is not implemented yet"); @@ -3385,6 +3395,13 @@ static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, queue.begin(), name); } +static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, + semantics::SemanticsContext &semaCtx, + lower::pft::Evaluation &eval, + const parser::OpenMPErrorConstruct &) { + TODO(converter.getCurrentLocation(), "OpenMPErrorConstruct"); +} + static void genOMP(lower::AbstractConverter &converter, lower::SymMap &symTable, semantics::SemanticsContext &semaCtx, lower::pft::Evaluation &eval, diff --git a/flang/lib/Optimizer/Builder/HLFIRTools.cpp b/flang/lib/Optimizer/Builder/HLFIRTools.cpp index 1bd950f2445ee..94238bc24e453 100644 --- a/flang/lib/Optimizer/Builder/HLFIRTools.cpp +++ b/flang/lib/Optimizer/Builder/HLFIRTools.cpp @@ -910,6 +910,56 @@ hlfir::LoopNest hlfir::genLoopNest(mlir::Location loc, return loopNest; } +llvm::SmallVector hlfir::genLoopNestWithReductions( + mlir::Location loc, fir::FirOpBuilder &builder, mlir::ValueRange extents, + mlir::ValueRange reductionInits, const ReductionLoopBodyGenerator &genBody, + bool isUnordered) { + assert(!extents.empty() && "must have at least one extent"); + // Build loop nest from column to row. + auto one = builder.create(loc, 1); + mlir::Type indexType = builder.getIndexType(); + unsigned dim = extents.size() - 1; + fir::DoLoopOp outerLoop = nullptr; + fir::DoLoopOp parentLoop = nullptr; + llvm::SmallVector oneBasedIndices; + oneBasedIndices.resize(dim + 1); + for (auto extent : llvm::reverse(extents)) { + auto ub = builder.createConvert(loc, indexType, extent); + + // The outermost loop takes reductionInits as the initial + // values of its iter-args. + // A child loop takes its iter-args from the region iter-args + // of its parent loop. + fir::DoLoopOp doLoop; + if (!parentLoop) { + doLoop = builder.create(loc, one, ub, one, isUnordered, + /*finalCountValue=*/false, + reductionInits); + } else { + doLoop = builder.create(loc, one, ub, one, isUnordered, + /*finalCountValue=*/false, + parentLoop.getRegionIterArgs()); + // Return the results of the child loop from its parent loop. + builder.create(loc, doLoop.getResults()); + } + + builder.setInsertionPointToStart(doLoop.getBody()); + // Reverse the indices so they are in column-major order. + oneBasedIndices[dim--] = doLoop.getInductionVar(); + if (!outerLoop) + outerLoop = doLoop; + parentLoop = doLoop; + } + + llvm::SmallVector reductionValues; + reductionValues = + genBody(loc, builder, oneBasedIndices, parentLoop.getRegionIterArgs()); + builder.setInsertionPointToEnd(parentLoop.getBody()); + builder.create(loc, reductionValues); + builder.setInsertionPointAfter(outerLoop); + return outerLoop->getResults(); +} + static fir::ExtendedValue translateVariableToExtendedValue( mlir::Location loc, fir::FirOpBuilder &builder, hlfir::Entity variable, bool forceHlfirBase = false, bool contiguousHint = false) { diff --git a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp index 2758da48bceca..547cebefd2df4 100644 --- a/flang/lib/Optimizer/Builder/IntrinsicCall.cpp +++ b/flang/lib/Optimizer/Builder/IntrinsicCall.cpp @@ -41,7 +41,7 @@ #include "flang/Optimizer/Support/FatalError.h" #include "flang/Optimizer/Support/Utils.h" #include "flang/Runtime/entry-names.h" -#include "flang/Runtime/iostat.h" +#include "flang/Runtime/iostat-consts.h" #include "mlir/Dialect/Complex/IR/Complex.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Dialect/Math/IR/Math.h" diff --git a/flang/lib/Optimizer/Builder/Runtime/Allocatable.cpp b/flang/lib/Optimizer/Builder/Runtime/Allocatable.cpp index 28452d3b486da..70a88ff18cb1d 100644 --- a/flang/lib/Optimizer/Builder/Runtime/Allocatable.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/Allocatable.cpp @@ -76,19 +76,16 @@ void fir::runtime::genAllocatableAllocate(fir::FirOpBuilder &builder, mlir::func::FuncOp func{ fir::runtime::getRuntimeFunc(loc, builder)}; mlir::FunctionType fTy{func.getFunctionType()}; - mlir::Value asyncId = - builder.createIntegerConstant(loc, builder.getI64Type(), -1); mlir::Value sourceFile{fir::factory::locationToFilename(builder, loc)}; mlir::Value sourceLine{ - fir::factory::locationToLineNo(builder, loc, fTy.getInput(5))}; + fir::factory::locationToLineNo(builder, loc, fTy.getInput(4))}; if (!hasStat) hasStat = builder.createBool(loc, false); if (!errMsg) { mlir::Type boxNoneTy = fir::BoxType::get(builder.getNoneType()); errMsg = builder.create(loc, boxNoneTy).getResult(); } - llvm::SmallVector args{ - fir::runtime::createArguments(builder, loc, fTy, desc, asyncId, hasStat, - errMsg, sourceFile, sourceLine)}; + llvm::SmallVector args{fir::runtime::createArguments( + builder, loc, fTy, desc, hasStat, errMsg, sourceFile, sourceLine)}; builder.create(loc, func, args); } diff --git a/flang/lib/Optimizer/Builder/Runtime/ArrayConstructor.cpp b/flang/lib/Optimizer/Builder/Runtime/ArrayConstructor.cpp index c786bef5cb1c4..0d56cd2edc99b 100644 --- a/flang/lib/Optimizer/Builder/Runtime/ArrayConstructor.cpp +++ b/flang/lib/Optimizer/Builder/Runtime/ArrayConstructor.cpp @@ -9,7 +9,7 @@ #include "flang/Optimizer/Builder/Runtime/ArrayConstructor.h" #include "flang/Optimizer/Builder/FIRBuilder.h" #include "flang/Optimizer/Builder/Runtime/RTBuilder.h" -#include "flang/Runtime/array-constructor.h" +#include "flang/Runtime/array-constructor-consts.h" using namespace Fortran::runtime; @@ -25,12 +25,13 @@ mlir::Value fir::runtime::genInitArrayConstructorVector( mlir::Location loc, fir::FirOpBuilder &builder, mlir::Value toBox, mlir::Value useValueLengthParameters) { // Allocate storage for the runtime cookie for the array constructor vector. - // Use the "host" size and alignment, but double them to be safe regardless of - // the target. The "cookieSize" argument is used to validate this wild - // assumption until runtime interfaces are improved. + // Use pessimistic values for size and alignment that are valid for all + // supported targets. Whether the actual ArrayConstructorVector object fits + // into the available MaxArrayConstructorVectorSizeInBytes is verified when + // building clang-rt. std::size_t arrayVectorStructBitSize = - 2 * sizeof(Fortran::runtime::ArrayConstructorVector) * 8; - std::size_t alignLike = alignof(Fortran::runtime::ArrayConstructorVector) * 8; + MaxArrayConstructorVectorSizeInBytes * 8; + std::size_t alignLike = MaxArrayConstructorVectorAlignInBytes * 8; fir::SequenceType::Extent numElem = (arrayVectorStructBitSize + alignLike - 1) / alignLike; mlir::Type intType = builder.getIntegerType(alignLike); @@ -43,14 +44,12 @@ mlir::Value fir::runtime::genInitArrayConstructorVector( loc, builder); mlir::FunctionType funcType = func.getFunctionType(); cookie = builder.createConvert(loc, funcType.getInput(0), cookie); - mlir::Value cookieSize = builder.createIntegerConstant( - loc, funcType.getInput(3), numElem * alignLike / 8); mlir::Value sourceFile = fir::factory::locationToFilename(builder, loc); mlir::Value sourceLine = - fir::factory::locationToLineNo(builder, loc, funcType.getInput(5)); + fir::factory::locationToLineNo(builder, loc, funcType.getInput(4)); auto args = fir::runtime::createArguments(builder, loc, funcType, cookie, toBox, useValueLengthParameters, - cookieSize, sourceFile, sourceLine); + sourceFile, sourceLine); builder.create(loc, func, args); return cookie; } diff --git a/flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp b/flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp index c536fd19fcc69..1bb91d252529f 100644 --- a/flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp +++ b/flang/lib/Optimizer/CodeGen/BoxedProcedure.cpp @@ -103,6 +103,8 @@ class BoxprocTypeRewriter : public mlir::TypeConverter { return needsConversion(unwrapRefType(ty)); if (auto t = mlir::dyn_cast(ty)) return needsConversion(unwrapSequenceType(ty)); + if (auto t = mlir::dyn_cast(ty)) + return needsConversion(t.getOfTy()); return false; } @@ -167,6 +169,9 @@ class BoxprocTypeRewriter : public mlir::TypeConverter { rec.finalize(ps, cs); return rec; }); + addConversion([&](TypeDescType ty) { + return TypeDescType::get(convertType(ty.getOfTy())); + }); addArgumentMaterialization(materializeProcedure); addSourceMaterialization(materializeProcedure); addTargetMaterialization(materializeProcedure); @@ -220,7 +225,6 @@ class BoxedProcedurePass auto *context = &getContext(); mlir::IRRewriter rewriter(context); BoxprocTypeRewriter typeConverter(mlir::UnknownLoc::get(context)); - mlir::Dialect *firDialect = context->getLoadedDialect("fir"); getModule().walk([&](mlir::Operation *op) { bool opIsValid = true; typeConverter.setLocation(op->getLoc()); @@ -366,13 +370,22 @@ class BoxedProcedurePass index, toTy, index.getFieldId(), toOnTy, index.getTypeparams()); opIsValid = false; } - } else if (op->getDialect() == firDialect) { + } else { rewriter.startOpModification(op); + // Convert the operands if needed for (auto i : llvm::enumerate(op->getResultTypes())) if (typeConverter.needsConversion(i.value())) { auto toTy = typeConverter.convertType(i.value()); op->getResult(i.index()).setType(toTy); } + + // Convert the type attributes if needed + for (const mlir::NamedAttribute &attr : op->getAttrDictionary()) + if (auto tyAttr = llvm::dyn_cast(attr.getValue())) + if (typeConverter.needsConversion(tyAttr.getValue())) { + auto toTy = typeConverter.convertType(tyAttr.getValue()); + op->setAttr(attr.getName(), mlir::TypeAttr::get(toTy)); + } rewriter.finalizeOpModification(op); } // Ensure block arguments are updated if needed. diff --git a/flang/lib/Optimizer/CodeGen/CodeGen.cpp b/flang/lib/Optimizer/CodeGen/CodeGen.cpp index 76cd2d294c1b1..073ba0858fa3f 100644 --- a/flang/lib/Optimizer/CodeGen/CodeGen.cpp +++ b/flang/lib/Optimizer/CodeGen/CodeGen.cpp @@ -23,8 +23,9 @@ #include "flang/Optimizer/Support/InternalNames.h" #include "flang/Optimizer/Support/TypeCode.h" #include "flang/Optimizer/Support/Utils.h" -#include "flang/Runtime/allocator-registry.h" -#include "flang/Runtime/descriptor.h" +#include "flang/Runtime/CUDA/descriptor.h" +#include "flang/Runtime/allocator-registry-consts.h" +#include "flang/Runtime/descriptor-consts.h" #include "flang/Semantics/runtime-type-info.h" #include "mlir/Conversion/ArithCommon/AttrToLLVMConverter.h" #include "mlir/Conversion/ArithToLLVM/ArithToLLVM.h" @@ -1365,16 +1366,12 @@ struct EmboxCommonConversion : public fir::FIROpConversion { insertField(rewriter, loc, descriptor, {kExtraPosInBox}, extraField); } else { // Compute the value of the extra field based on allocator_idx and - // addendum present using a Descriptor object. - Fortran::runtime::StaticDescriptor staticDescriptor; - Fortran::runtime::Descriptor &desc{staticDescriptor.descriptor()}; - desc.raw().extra = 0; - desc.SetAllocIdx(allocatorIdx); + // addendum present. + unsigned extra = allocatorIdx << _CFI_ALLOCATOR_IDX_SHIFT; if (hasAddendum) - desc.SetHasAddendum(); - descriptor = - insertField(rewriter, loc, descriptor, {kExtraPosInBox}, - this->genI32Constant(loc, rewriter, desc.raw().extra)); + extra |= _CFI_ADDENDUM_FLAG; + descriptor = insertField(rewriter, loc, descriptor, {kExtraPosInBox}, + this->genI32Constant(loc, rewriter, extra)); } if (hasAddendum) { @@ -3021,6 +3018,93 @@ struct GlobalOpConversion : public fir::FIROpConversion { } }; +static mlir::Value genSourceFile(mlir::Location loc, mlir::ModuleOp mod, + mlir::ConversionPatternRewriter &rewriter) { + auto ptrTy = mlir::LLVM::LLVMPointerType::get(rewriter.getContext()); + if (auto flc = mlir::dyn_cast(loc)) { + auto fn = flc.getFilename().str() + '\0'; + std::string globalName = fir::factory::uniqueCGIdent("cl", fn); + + if (auto g = mod.lookupSymbol(globalName)) { + return rewriter.create(loc, ptrTy, g.getName()); + } else if (auto g = mod.lookupSymbol(globalName)) { + return rewriter.create(loc, ptrTy, g.getName()); + } + + auto crtInsPt = rewriter.saveInsertionPoint(); + rewriter.setInsertionPoint(mod.getBody(), mod.getBody()->end()); + auto arrayTy = mlir::LLVM::LLVMArrayType::get( + mlir::IntegerType::get(rewriter.getContext(), 8), fn.size()); + mlir::LLVM::GlobalOp globalOp = rewriter.create( + loc, arrayTy, /*constant=*/true, mlir::LLVM::Linkage::Linkonce, + globalName, mlir::Attribute()); + + mlir::Region ®ion = globalOp.getInitializerRegion(); + mlir::Block *block = rewriter.createBlock(®ion); + rewriter.setInsertionPoint(block, block->begin()); + mlir::Value constValue = rewriter.create( + loc, arrayTy, rewriter.getStringAttr(fn)); + rewriter.create(loc, constValue); + rewriter.restoreInsertionPoint(crtInsPt); + return rewriter.create(loc, ptrTy, + globalOp.getName()); + } + return rewriter.create(loc, ptrTy); +} + +static mlir::Value genSourceLine(mlir::Location loc, + mlir::ConversionPatternRewriter &rewriter) { + if (auto flc = mlir::dyn_cast(loc)) + return rewriter.create(loc, rewriter.getI32Type(), + flc.getLine()); + return rewriter.create(loc, rewriter.getI32Type(), 0); +} + +static mlir::Value +genCUFAllocDescriptor(mlir::Location loc, + mlir::ConversionPatternRewriter &rewriter, + mlir::ModuleOp mod, fir::BaseBoxType boxTy, + const fir::LLVMTypeConverter &typeConverter) { + std::optional dl = + fir::support::getOrSetDataLayout(mod, /*allowDefaultLayout=*/true); + if (!dl) + mlir::emitError(mod.getLoc(), + "module operation must carry a data layout attribute " + "to generate llvm IR from FIR"); + + mlir::Value sourceFile = genSourceFile(loc, mod, rewriter); + mlir::Value sourceLine = genSourceLine(loc, rewriter); + + mlir::MLIRContext *ctx = mod.getContext(); + + mlir::LLVM::LLVMPointerType llvmPointerType = + mlir::LLVM::LLVMPointerType::get(ctx); + mlir::Type llvmInt32Type = mlir::IntegerType::get(ctx, 32); + mlir::Type llvmIntPtrType = + mlir::IntegerType::get(ctx, typeConverter.getPointerBitwidth(0)); + auto fctTy = mlir::LLVM::LLVMFunctionType::get( + llvmPointerType, {llvmIntPtrType, llvmPointerType, llvmInt32Type}); + + auto llvmFunc = mod.lookupSymbol( + RTNAME_STRING(CUFAllocDesciptor)); + auto funcFunc = + mod.lookupSymbol(RTNAME_STRING(CUFAllocDesciptor)); + if (!llvmFunc && !funcFunc) + mlir::OpBuilder::atBlockEnd(mod.getBody()) + .create(loc, RTNAME_STRING(CUFAllocDesciptor), + fctTy); + + mlir::Type structTy = typeConverter.convertBoxTypeAsStruct(boxTy); + std::size_t boxSize = dl->getTypeSizeInBits(structTy) / 8; + mlir::Value sizeInBytes = + genConstantIndex(loc, llvmIntPtrType, rewriter, boxSize); + llvm::SmallVector args = {sizeInBytes, sourceFile, sourceLine}; + return rewriter + .create(loc, fctTy, RTNAME_STRING(CUFAllocDesciptor), + args) + .getResult(); +} + /// `fir.load` --> `llvm.load` struct LoadOpConversion : public fir::FIROpConversion { using FIROpConversion::FIROpConversion; @@ -3037,9 +3121,23 @@ struct LoadOpConversion : public fir::FIROpConversion { // loading a fir.ref is implemented as taking a snapshot of the // descriptor value into a new descriptor temp. auto inputBoxStorage = adaptor.getOperands()[0]; + mlir::Value newBoxStorage; mlir::Location loc = load.getLoc(); - auto newBoxStorage = - genAllocaAndAddrCastWithType(loc, llvmLoadTy, defaultAlign, rewriter); + if (auto callOp = mlir::dyn_cast_or_null( + inputBoxStorage.getDefiningOp())) { + if (callOp.getCallee() && + (*callOp.getCallee()) + .starts_with(RTNAME_STRING(CUFAllocDesciptor))) { + // CUDA Fortran local descriptor are allocated in managed memory. So + // new storage must be allocated the same way. + auto mod = load->getParentOfType(); + newBoxStorage = + genCUFAllocDescriptor(loc, rewriter, mod, boxTy, lowerTy()); + } + } + if (!newBoxStorage) + newBoxStorage = genAllocaAndAddrCastWithType(loc, llvmLoadTy, + defaultAlign, rewriter); TypePair boxTypePair{boxTy, llvmLoadTy}; mlir::Value boxSize = diff --git a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp index 1b86d5241704b..b0b9499557e2b 100644 --- a/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp +++ b/flang/lib/Optimizer/CodeGen/TargetRewrite.cpp @@ -62,14 +62,21 @@ struct FixupTy { FixupTy(Codes code, std::size_t index, std::function &&finalizer) : code{code}, index{index}, finalizer{finalizer} {} + FixupTy(Codes code, std::size_t index, + std::function &&finalizer) + : code{code}, index{index}, gpuFinalizer{finalizer} {} FixupTy(Codes code, std::size_t index, std::size_t second, std::function &&finalizer) : code{code}, index{index}, second{second}, finalizer{finalizer} {} + FixupTy(Codes code, std::size_t index, std::size_t second, + std::function &&finalizer) + : code{code}, index{index}, second{second}, gpuFinalizer{finalizer} {} Codes code; std::size_t index; std::size_t second{}; std::optional> finalizer{}; + std::optional> gpuFinalizer{}; }; // namespace /// Target-specific rewriting of the FIR. This is a prerequisite pass to code @@ -127,10 +134,18 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { mod.walk([&](mlir::Operation *op) { if (auto call = mlir::dyn_cast(op)) { if (!hasPortableSignature(call.getFunctionType(), op)) - convertCallOp(call); + convertCallOp(call, call.getFunctionType()); } else if (auto dispatch = mlir::dyn_cast(op)) { if (!hasPortableSignature(dispatch.getFunctionType(), op)) - convertCallOp(dispatch); + convertCallOp(dispatch, dispatch.getFunctionType()); + } else if (auto gpuLaunchFunc = + mlir::dyn_cast(op)) { + llvm::SmallVector operandsTypes; + for (auto arg : gpuLaunchFunc.getKernelOperands()) + operandsTypes.push_back(arg.getType()); + auto fctTy = mlir::FunctionType::get(&context, operandsTypes, {}); + if (!hasPortableSignature(fctTy, op)) + convertCallOp(gpuLaunchFunc, fctTy); } else if (auto addr = mlir::dyn_cast(op)) { if (mlir::isa(addr.getType()) && !hasPortableSignature(addr.getType(), op)) @@ -350,8 +365,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { // Convert fir.call and fir.dispatch Ops. template - void convertCallOp(A callOp) { - auto fnTy = callOp.getFunctionType(); + void convertCallOp(A callOp, mlir::FunctionType fnTy) { auto loc = callOp.getLoc(); rewriter->setInsertionPoint(callOp); llvm::SmallVector newResTys; @@ -369,7 +383,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { newOpers.push_back(callOp.getOperand(0)); dropFront = 1; } - } else { + } else if constexpr (std::is_same_v, fir::DispatchOp>) { dropFront = 1; // First operand is the polymorphic object. } @@ -395,10 +409,14 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { llvm::SmallVector trailingInTys; llvm::SmallVector trailingOpers; + llvm::SmallVector operands; unsigned passArgShift = 0; + if constexpr (std::is_same_v, mlir::gpu::LaunchFuncOp>) + operands = callOp.getKernelOperands(); + else + operands = callOp.getOperands().drop_front(dropFront); for (auto e : llvm::enumerate( - llvm::zip(fnTy.getInputs().drop_front(dropFront), - callOp.getOperands().drop_front(dropFront)))) { + llvm::zip(fnTy.getInputs().drop_front(dropFront), operands))) { mlir::Type ty = std::get<0>(e.value()); mlir::Value oper = std::get<1>(e.value()); unsigned index = e.index(); @@ -500,7 +518,19 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { newOpers.insert(newOpers.end(), trailingOpers.begin(), trailingOpers.end()); llvm::SmallVector newCallResults; - if constexpr (std::is_same_v, fir::CallOp>) { + if constexpr (std::is_same_v, mlir::gpu::LaunchFuncOp>) { + auto newCall = rewriter->create( + loc, callOp.getKernel(), callOp.getGridSizeOperandValues(), + callOp.getBlockSizeOperandValues(), + callOp.getDynamicSharedMemorySize(), newOpers); + if (callOp.getClusterSizeX()) + newCall.getClusterSizeXMutable().assign(callOp.getClusterSizeX()); + if (callOp.getClusterSizeY()) + newCall.getClusterSizeYMutable().assign(callOp.getClusterSizeY()); + if (callOp.getClusterSizeZ()) + newCall.getClusterSizeZMutable().assign(callOp.getClusterSizeZ()); + newCallResults.append(newCall.result_begin(), newCall.result_end()); + } else if constexpr (std::is_same_v, fir::CallOp>) { fir::CallOp newCall; if (callOp.getCallee()) { newCall = @@ -719,12 +749,15 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { if (targetFeaturesAttr) fn->setAttr("target_features", targetFeaturesAttr); - convertSignature(fn); + convertSignature(fn); } - for (auto gpuMod : mod.getOps()) + for (auto gpuMod : mod.getOps()) { for (auto fn : gpuMod.getOps()) - convertSignature(fn); + convertSignature(fn); + for (auto fn : gpuMod.getOps()) + convertSignature(fn); + } return mlir::success(); } @@ -770,17 +803,20 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { /// Determine if the signature has host associations. The host association /// argument may need special target specific rewriting. - static bool hasHostAssociations(mlir::func::FuncOp func) { + template + static bool hasHostAssociations(OpTy func) { std::size_t end = func.getFunctionType().getInputs().size(); for (std::size_t i = 0; i < end; ++i) - if (func.getArgAttrOfType(i, fir::getHostAssocAttrName())) + if (func.template getArgAttrOfType( + i, fir::getHostAssocAttrName())) return true; return false; } /// Rewrite the signatures and body of the `FuncOp`s in the module for /// the immediately subsequent target code gen. - void convertSignature(mlir::func::FuncOp func) { + template + void convertSignature(FuncOpTy func) { auto funcTy = mlir::cast(func.getFunctionType()); if (hasPortableSignature(funcTy, func) && !hasHostAssociations(func)) return; @@ -805,13 +841,13 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { // Convert return value(s) for (auto ty : funcTy.getResults()) llvm::TypeSwitch(ty) - .Case([&](mlir::ComplexType cmplx) { + .template Case([&](mlir::ComplexType cmplx) { if (noComplexConversion) newResTys.push_back(cmplx); else doComplexReturn(func, cmplx, newResTys, newInTyAndAttrs, fixups); }) - .Case([&](mlir::IntegerType intTy) { + .template Case([&](mlir::IntegerType intTy) { auto m = specifics->integerArgumentType(func.getLoc(), intTy); assert(m.size() == 1); auto attr = std::get(m[0]); @@ -825,7 +861,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { rewriter->getUnitAttr())); newResTys.push_back(retTy); }) - .Case([&](fir::RecordType recTy) { + .template Case([&](fir::RecordType recTy) { doStructReturn(func, recTy, newResTys, newInTyAndAttrs, fixups); }) .Default([&](mlir::Type ty) { newResTys.push_back(ty); }); @@ -840,7 +876,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { auto ty = e.value(); unsigned index = e.index(); llvm::TypeSwitch(ty) - .Case([&](fir::BoxCharType boxTy) { + .template Case([&](fir::BoxCharType boxTy) { if (noCharacterConversion) { newInTyAndAttrs.push_back( fir::CodeGenSpecifics::getTypeAndAttr(boxTy)); @@ -863,10 +899,10 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { } } }) - .Case([&](mlir::ComplexType cmplx) { + .template Case([&](mlir::ComplexType cmplx) { doComplexArg(func, cmplx, newInTyAndAttrs, fixups); }) - .Case([&](mlir::TupleType tuple) { + .template Case([&](mlir::TupleType tuple) { if (fir::isCharacterProcedureTuple(tuple)) { fixups.emplace_back(FixupTy::Codes::TrailingCharProc, newInTyAndAttrs.size(), trailingTys.size()); @@ -878,7 +914,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { fir::CodeGenSpecifics::getTypeAndAttr(ty)); } }) - .Case([&](mlir::IntegerType intTy) { + .template Case([&](mlir::IntegerType intTy) { auto m = specifics->integerArgumentType(func.getLoc(), intTy); assert(m.size() == 1); auto attr = std::get(m[0]); @@ -887,7 +923,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { if (!extensionAttrName.empty() && isFuncWithCCallingConvention(func)) fixups.emplace_back(FixupTy::Codes::ArgumentType, argNo, - [=](mlir::func::FuncOp func) { + [=](FuncOpTy func) { func.setArgAttr( argNo, extensionAttrName, mlir::UnitAttr::get(func.getContext())); @@ -903,8 +939,8 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { fir::CodeGenSpecifics::getTypeAndAttr(ty)); }); - if (func.getArgAttrOfType(index, - fir::getHostAssocAttrName())) { + if (func.template getArgAttrOfType( + index, fir::getHostAssocAttrName())) { extraAttrs.push_back( {newInTyAndAttrs.size() - 1, rewriter->getNamedAttr("llvm.nest", rewriter->getUnitAttr())}); @@ -979,27 +1015,27 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { auto newArg = func.front().insertArgument(fixup.index, fixupType, loc); offset++; - func.walk([&](mlir::func::ReturnOp ret) { + func.walk([&](ReturnOpTy ret) { rewriter->setInsertionPoint(ret); auto oldOper = ret.getOperand(0); auto oldOperTy = fir::ReferenceType::get(oldOper.getType()); auto cast = rewriter->create(loc, oldOperTy, newArg); rewriter->create(loc, oldOper, cast); - rewriter->create(loc); + rewriter->create(loc); ret.erase(); }); } break; case FixupTy::Codes::ReturnType: { // The function is still returning a value, but its type has likely // changed to suit the target ABI convention. - func.walk([&](mlir::func::ReturnOp ret) { + func.walk([&](ReturnOpTy ret) { rewriter->setInsertionPoint(ret); auto oldOper = ret.getOperand(0); mlir::Value bitcast = convertValueInMemory(loc, oldOper, newResTys[fixup.index], /*inputMayBeBigger=*/false); - rewriter->create(loc, bitcast); + rewriter->create(loc, bitcast); ret.erase(); }); } break; @@ -1101,13 +1137,18 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { } } - for (auto &fixup : fixups) - if (fixup.finalizer) - (*fixup.finalizer)(func); + for (auto &fixup : fixups) { + if constexpr (std::is_same_v) + if (fixup.finalizer) + (*fixup.finalizer)(func); + if constexpr (std::is_same_v) + if (fixup.gpuFinalizer) + (*fixup.gpuFinalizer)(func); + } } - template - void doReturn(mlir::func::FuncOp func, Ty &newResTys, + template + void doReturn(OpTy func, Ty &newResTys, fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs, FIXUPS &fixups, fir::CodeGenSpecifics::Marshalling &m) { assert(m.size() == 1 && @@ -1119,7 +1160,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { unsigned argNo = newInTyAndAttrs.size(); if (auto align = attr.getAlignment()) fixups.emplace_back( - FixupTy::Codes::ReturnAsStore, argNo, [=](mlir::func::FuncOp func) { + FixupTy::Codes::ReturnAsStore, argNo, [=](OpTy func) { auto elemType = fir::dyn_cast_ptrOrBoxEleTy( func.getFunctionType().getInput(argNo)); func.setArgAttr(argNo, "llvm.sret", @@ -1130,7 +1171,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { }); else fixups.emplace_back(FixupTy::Codes::ReturnAsStore, argNo, - [=](mlir::func::FuncOp func) { + [=](OpTy func) { auto elemType = fir::dyn_cast_ptrOrBoxEleTy( func.getFunctionType().getInput(argNo)); func.setArgAttr(argNo, "llvm.sret", @@ -1141,8 +1182,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { } if (auto align = attr.getAlignment()) fixups.emplace_back( - FixupTy::Codes::ReturnType, newResTys.size(), - [=](mlir::func::FuncOp func) { + FixupTy::Codes::ReturnType, newResTys.size(), [=](OpTy func) { func.setArgAttr( newResTys.size(), "llvm.align", rewriter->getIntegerAttr(rewriter->getIntegerType(32), align)); @@ -1155,9 +1195,8 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { /// Convert a complex return value. This can involve converting the return /// value to a "hidden" first argument or packing the complex into a wide /// GPR. - template - void doComplexReturn(mlir::func::FuncOp func, mlir::ComplexType cmplx, - Ty &newResTys, + template + void doComplexReturn(OpTy func, mlir::ComplexType cmplx, Ty &newResTys, fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs, FIXUPS &fixups) { if (noComplexConversion) { @@ -1169,9 +1208,8 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { doReturn(func, newResTys, newInTyAndAttrs, fixups, m); } - template - void doStructReturn(mlir::func::FuncOp func, fir::RecordType recTy, - Ty &newResTys, + template + void doStructReturn(OpTy func, fir::RecordType recTy, Ty &newResTys, fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs, FIXUPS &fixups) { if (noStructConversion) { @@ -1182,12 +1220,10 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { doReturn(func, newResTys, newInTyAndAttrs, fixups, m); } - template - void - createFuncOpArgFixups(mlir::func::FuncOp func, - fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs, - fir::CodeGenSpecifics::Marshalling &argsInTys, - FIXUPS &fixups) { + template + void createFuncOpArgFixups( + OpTy func, fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs, + fir::CodeGenSpecifics::Marshalling &argsInTys, FIXUPS &fixups) { const auto fixupCode = argsInTys.size() > 1 ? FixupTy::Codes::Split : FixupTy::Codes::ArgumentType; for (auto e : llvm::enumerate(argsInTys)) { @@ -1198,7 +1234,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { if (attr.isByVal()) { if (auto align = attr.getAlignment()) fixups.emplace_back(FixupTy::Codes::ArgumentAsLoad, argNo, - [=](mlir::func::FuncOp func) { + [=](OpTy func) { auto elemType = fir::dyn_cast_ptrOrBoxEleTy( func.getFunctionType().getInput(argNo)); func.setArgAttr(argNo, "llvm.byval", @@ -1210,8 +1246,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { }); else fixups.emplace_back(FixupTy::Codes::ArgumentAsLoad, - newInTyAndAttrs.size(), - [=](mlir::func::FuncOp func) { + newInTyAndAttrs.size(), [=](OpTy func) { auto elemType = fir::dyn_cast_ptrOrBoxEleTy( func.getFunctionType().getInput(argNo)); func.setArgAttr(argNo, "llvm.byval", @@ -1220,7 +1255,7 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { } else { if (auto align = attr.getAlignment()) fixups.emplace_back( - fixupCode, argNo, index, [=](mlir::func::FuncOp func) { + fixupCode, argNo, index, [=](OpTy func) { func.setArgAttr(argNo, "llvm.align", rewriter->getIntegerAttr( rewriter->getIntegerType(32), align)); @@ -1235,8 +1270,8 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { /// Convert a complex argument value. This can involve storing the value to /// a temporary memory location or factoring the value into two distinct /// arguments. - template - void doComplexArg(mlir::func::FuncOp func, mlir::ComplexType cmplx, + template + void doComplexArg(OpTy func, mlir::ComplexType cmplx, fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs, FIXUPS &fixups) { if (noComplexConversion) { @@ -1248,8 +1283,8 @@ class TargetRewrite : public fir::impl::TargetRewritePassBase { createFuncOpArgFixups(func, newInTyAndAttrs, cplxArgs, fixups); } - template - void doStructArg(mlir::func::FuncOp func, fir::RecordType recTy, + template + void doStructArg(OpTy func, fir::RecordType recTy, fir::CodeGenSpecifics::Marshalling &newInTyAndAttrs, FIXUPS &fixups) { if (noStructConversion) { diff --git a/flang/lib/Optimizer/Dialect/CUF/CUFToLLVMIRTranslation.cpp b/flang/lib/Optimizer/Dialect/CUF/CUFToLLVMIRTranslation.cpp index 63eac46a99771..0c1424d11b515 100644 --- a/flang/lib/Optimizer/Dialect/CUF/CUFToLLVMIRTranslation.cpp +++ b/flang/lib/Optimizer/Dialect/CUF/CUFToLLVMIRTranslation.cpp @@ -66,8 +66,12 @@ LogicalResult registerKernel(cuf::RegisterKernelOp op, llvm::FunctionType::get( ptrTy, ArrayRef({ptrTy, ptrTy, ptrTy}), false)); llvm::Value *modulePtr = moduleTranslation.lookupValue(op.getModulePtr()); + if (!modulePtr) + return op.emitError() << "Couldn't find the module ptr"; llvm::Function *fctSym = moduleTranslation.lookupFunction(op.getKernelName().str()); + if (!fctSym) + return op.emitError() << "Couldn't find kernel name symbol"; builder.CreateCall(fct, {modulePtr, fctSym, getOrCreateFunctionName( module, builder, op.getKernelModuleName().str(), diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIRDialect.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIRDialect.cpp index d67b5fa659807..cb77aef74acd5 100644 --- a/flang/lib/Optimizer/HLFIR/IR/HLFIRDialect.cpp +++ b/flang/lib/Optimizer/HLFIR/IR/HLFIRDialect.cpp @@ -228,3 +228,12 @@ mlir::Type hlfir::getExprType(mlir::Type variableType) { return hlfir::ExprType::get(variableType.getContext(), typeShape, type, isPolymorphic); } + +bool hlfir::isFortranIntegerScalarOrArrayObject(mlir::Type type) { + if (isBoxAddressType(type)) + return false; + + mlir::Type unwrappedType = fir::unwrapPassByRefType(fir::unwrapRefType(type)); + mlir::Type elementType = getFortranElementType(unwrappedType); + return mlir::isa(elementType); +} diff --git a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp index 3a172d1b8b540..82aac7cafa1d0 100644 --- a/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp +++ b/flang/lib/Optimizer/HLFIR/IR/HLFIROps.cpp @@ -1341,6 +1341,108 @@ void hlfir::MatmulTransposeOp::getEffects( getIntrinsicEffects(getOperation(), effects); } +//===----------------------------------------------------------------------===// +// CShiftOp +//===----------------------------------------------------------------------===// + +llvm::LogicalResult hlfir::CShiftOp::verify() { + mlir::Value array = getArray(); + fir::SequenceType arrayTy = mlir::cast( + hlfir::getFortranElementOrSequenceType(array.getType())); + llvm::ArrayRef inShape = arrayTy.getShape(); + std::size_t arrayRank = inShape.size(); + mlir::Type eleTy = arrayTy.getEleTy(); + hlfir::ExprType resultTy = mlir::cast(getResult().getType()); + llvm::ArrayRef resultShape = resultTy.getShape(); + std::size_t resultRank = resultShape.size(); + mlir::Type resultEleTy = resultTy.getEleTy(); + mlir::Value shift = getShift(); + mlir::Type shiftTy = hlfir::getFortranElementOrSequenceType(shift.getType()); + + if (eleTy != resultEleTy) { + if (mlir::isa(eleTy) && + mlir::isa(resultEleTy)) { + auto eleCharTy = mlir::cast(eleTy); + auto resultCharTy = mlir::cast(resultEleTy); + if (eleCharTy.getFKind() != resultCharTy.getFKind()) + return emitOpError("kind mismatch between input and output arrays"); + if (eleCharTy.getLen() != fir::CharacterType::unknownLen() && + resultCharTy.getLen() != fir::CharacterType::unknownLen() && + eleCharTy.getLen() != resultCharTy.getLen()) + return emitOpError( + "character LEN mismatch between input and output arrays"); + } else { + return emitOpError( + "input and output arrays should have the same element type"); + } + } + + if (arrayRank != resultRank) + return emitOpError("input and output arrays should have the same rank"); + + constexpr int64_t unknownExtent = fir::SequenceType::getUnknownExtent(); + for (auto [inDim, resultDim] : llvm::zip(inShape, resultShape)) + if (inDim != unknownExtent && resultDim != unknownExtent && + inDim != resultDim) + return emitOpError( + "output array's shape conflicts with the input array's shape"); + + int64_t dimVal = -1; + if (!getDim()) + dimVal = 1; + else if (auto dim = fir::getIntIfConstant(getDim())) + dimVal = *dim; + + // The DIM argument may be statically invalid (e.g. exceed the + // input array rank) in dead code after constant propagation, + // so avoid some checks unless useStrictIntrinsicVerifier is true. + if (useStrictIntrinsicVerifier && dimVal != -1) { + if (dimVal < 1) + return emitOpError("DIM must be >= 1"); + if (dimVal > static_cast(arrayRank)) + return emitOpError("DIM must be <= input array's rank"); + } + + if (auto shiftSeqTy = mlir::dyn_cast(shiftTy)) { + // SHIFT is an array. Verify the rank and the shape (if DIM is constant). + llvm::ArrayRef shiftShape = shiftSeqTy.getShape(); + std::size_t shiftRank = shiftShape.size(); + if (shiftRank != arrayRank - 1) + return emitOpError( + "SHIFT's rank must be 1 less than the input array's rank"); + + if (useStrictIntrinsicVerifier && dimVal != -1) { + // SHIFT's shape must be [d(1), d(2), ..., d(DIM-1), d(DIM+1), ..., d(n)], + // where [d(1), d(2), ..., d(n)] is the shape of the ARRAY. + int64_t arrayDimIdx = 0; + int64_t shiftDimIdx = 0; + for (auto shiftDim : shiftShape) { + if (arrayDimIdx == dimVal - 1) + ++arrayDimIdx; + + if (inShape[arrayDimIdx] != unknownExtent && + shiftDim != unknownExtent && inShape[arrayDimIdx] != shiftDim) + return emitOpError("SHAPE(ARRAY)(" + llvm::Twine(arrayDimIdx + 1) + + ") must be equal to SHAPE(SHIFT)(" + + llvm::Twine(shiftDimIdx + 1) + + "): " + llvm::Twine(inShape[arrayDimIdx]) + + " != " + llvm::Twine(shiftDim)); + ++arrayDimIdx; + ++shiftDimIdx; + } + } + } + + return mlir::success(); +} + +void hlfir::CShiftOp::getEffects( + llvm::SmallVectorImpl< + mlir::SideEffects::EffectInstance> + &effects) { + getIntrinsicEffects(getOperation(), effects); +} + //===----------------------------------------------------------------------===// // AssociateOp //===----------------------------------------------------------------------===// @@ -1602,6 +1704,15 @@ hlfir::ShapeOfOp::canonicalize(ShapeOfOp shapeOf, return llvm::LogicalResult::success(); } +mlir::OpFoldResult hlfir::ShapeOfOp::fold(FoldAdaptor adaptor) { + if (matchPattern(getExpr(), mlir::m_Op())) { + auto elementalOp = + mlir::cast(getExpr().getDefiningOp()); + return elementalOp.getShape(); + } + return {}; +} + //===----------------------------------------------------------------------===// // GetExtent //===----------------------------------------------------------------------===// diff --git a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp index 347f0a5630777..48e3db0eb39b6 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/BufferizeHLFIR.cpp @@ -806,8 +806,12 @@ struct ElementalOpConversion // elemental is a "view" over a variable (e.g parentheses or transpose). if (auto asExpr = elementValue.getDefiningOp()) { if (asExpr->hasOneUse() && !asExpr.isMove()) { - elementValue = hlfir::Entity{asExpr.getVar()}; - rewriter.eraseOp(asExpr); + // Check that the asExpr is the final operation before the yield, + // otherwise, clean-ups could impact the memory being re-used. + if (asExpr->getNextNode() == yield.getOperation()) { + elementValue = hlfir::Entity{asExpr.getVar()}; + rewriter.eraseOp(asExpr); + } } } rewriter.eraseOp(yield); diff --git a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp index bfb4148d93bfd..36fae90c83fd6 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/LowerHLFIRIntrinsics.cpp @@ -463,6 +463,37 @@ struct MatmulTransposeOpConversion } }; +class CShiftOpConversion : public HlfirIntrinsicConversion { + using HlfirIntrinsicConversion::HlfirIntrinsicConversion; + + llvm::LogicalResult + matchAndRewrite(hlfir::CShiftOp cshift, + mlir::PatternRewriter &rewriter) const override { + fir::FirOpBuilder builder{rewriter, cshift.getOperation()}; + const mlir::Location &loc = cshift->getLoc(); + + llvm::SmallVector inArgs; + mlir::Value array = cshift.getArray(); + inArgs.push_back({array, array.getType()}); + mlir::Value shift = cshift.getShift(); + inArgs.push_back({shift, shift.getType()}); + inArgs.push_back({cshift.getDim(), builder.getI32Type()}); + + auto *argLowering = fir::getIntrinsicArgumentLowering("cshift"); + llvm::SmallVector args = + lowerArguments(cshift, inArgs, rewriter, argLowering); + + mlir::Type scalarResultType = + hlfir::getFortranElementType(cshift.getType()); + + auto [resultExv, mustBeFreed] = + fir::genIntrinsicCall(builder, loc, "cshift", scalarResultType, args); + + processReturnValue(cshift, resultExv, mustBeFreed, builder, rewriter); + return mlir::success(); + } +}; + class LowerHLFIRIntrinsics : public hlfir::impl::LowerHLFIRIntrinsicsBase { public: @@ -475,7 +506,8 @@ class LowerHLFIRIntrinsics AllOpConversion, AnyOpConversion, SumOpConversion, ProductOpConversion, TransposeOpConversion, CountOpConversion, DotProductOpConversion, MaxvalOpConversion, MinvalOpConversion, - MinlocOpConversion, MaxlocOpConversion>(context); + MinlocOpConversion, MaxlocOpConversion, CShiftOpConversion>( + context); // While conceptually this pass is performing dialect conversion, we use // pattern rewrites here instead of dialect conversion because this pass diff --git a/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp b/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp index 9327e7ad5875c..c152c27c0a05b 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/OptimizedBufferization.cpp @@ -159,28 +159,162 @@ containsReadOrWriteEffectOn(const mlir::MemoryEffects::EffectInstance &effect, return mlir::AliasResult::NoAlias; } -// Returns true if the given array references represent identical -// or completely disjoint array slices. The callers may use this -// method when the alias analysis reports an alias of some kind, -// so that we can run Fortran specific analysis on the array slices -// to see if they are identical or disjoint. Note that the alias -// analysis are not able to give such an answer about the references. -static bool areIdenticalOrDisjointSlices(mlir::Value ref1, mlir::Value ref2) { +// Helper class for analyzing two array slices represented +// by two hlfir.designate operations. +class ArraySectionAnalyzer { +public: + // The result of the analyzis is one of the values below. + enum class SlicesOverlapKind { + // Slices overlap is unknown. + Unknown, + // Slices are definitely identical. + DefinitelyIdentical, + // Slices are definitely disjoint. + DefinitelyDisjoint, + // Slices may be either disjoint or identical, + // i.e. there is definitely no partial overlap. + EitherIdenticalOrDisjoint + }; + + // Analyzes two hlfir.designate results and returns the overlap kind. + // The callers may use this method when the alias analysis reports + // an alias of some kind, so that we can run Fortran specific analysis + // on the array slices to see if they are identical or disjoint. + // Note that the alias analysis are not able to give such an answer + // about the references. + static SlicesOverlapKind analyze(mlir::Value ref1, mlir::Value ref2); + +private: + struct SectionDesc { + // An array section is described by tuple. + // If the designator's subscript is not a triple, then + // the section descriptor is constructed as . + mlir::Value lb, ub, stride; + + SectionDesc(mlir::Value lb, mlir::Value ub, mlir::Value stride) + : lb(lb), ub(ub), stride(stride) { + assert(lb && "lower bound or index must be specified"); + normalize(); + } + + // Normalize the section descriptor: + // 1. If UB is nullptr, then it is set to LB. + // 2. If LB==UB, then stride does not matter, + // so it is reset to nullptr. + // 3. If STRIDE==1, then it is reset to nullptr. + void normalize() { + if (!ub) + ub = lb; + if (lb == ub) + stride = nullptr; + if (stride) + if (auto val = fir::getIntIfConstant(stride)) + if (*val == 1) + stride = nullptr; + } + + bool operator==(const SectionDesc &other) const { + return lb == other.lb && ub == other.ub && stride == other.stride; + } + }; + + // Given an operand_iterator over the indices operands, + // read the subscript values and return them as SectionDesc + // updating the iterator. If isTriplet is true, + // the subscript is a triplet, and the result is . + // Otherwise, the subscript is a scalar index, and the result + // is . + static SectionDesc readSectionDesc(mlir::Operation::operand_iterator &it, + bool isTriplet) { + if (isTriplet) + return {*it++, *it++, *it++}; + return {*it++, nullptr, nullptr}; + } + + // Return the ordered lower and upper bounds of the section. + // If stride is known to be non-negative, then the ordered + // bounds match the of the descriptor. + // If stride is known to be negative, then the ordered + // bounds are of the descriptor. + // If stride is unknown, we cannot deduce any order, + // so the result is + static std::pair + getOrderedBounds(const SectionDesc &desc) { + mlir::Value stride = desc.stride; + // Null stride means stride=1. + if (!stride) + return {desc.lb, desc.ub}; + // Reverse the bounds, if stride is negative. + if (auto val = fir::getIntIfConstant(stride)) { + if (*val >= 0) + return {desc.lb, desc.ub}; + else + return {desc.ub, desc.lb}; + } + + return {nullptr, nullptr}; + } + + // Given two array sections and + // , return true only if the sections + // are known to be disjoint. + // + // For example, for any positive constant C: + // X:Y does not overlap with (Y+C):Z + // X:Y does not overlap with Z:(X-C) + static bool areDisjointSections(const SectionDesc &desc1, + const SectionDesc &desc2) { + auto [lb1, ub1] = getOrderedBounds(desc1); + auto [lb2, ub2] = getOrderedBounds(desc2); + if (!lb1 || !lb2) + return false; + // Note that this comparison must be made on the ordered bounds, + // otherwise 'a(x:y:1) = a(z:x-1:-1) + 1' may be incorrectly treated + // as not overlapping (x=2, y=10, z=9). + if (isLess(ub1, lb2) || isLess(ub2, lb1)) + return true; + return false; + } + + // Given two array sections and + // , return true only if the sections + // are known to be identical. + // + // For example: + // + // + // + // These sections are identical, from the point of which array + // elements are being addresses, even though the shape + // of the array slices might be different. + static bool areIdenticalSections(const SectionDesc &desc1, + const SectionDesc &desc2) { + if (desc1 == desc2) + return true; + return false; + } + + // Return true, if v1 is known to be less than v2. + static bool isLess(mlir::Value v1, mlir::Value v2); +}; + +ArraySectionAnalyzer::SlicesOverlapKind +ArraySectionAnalyzer::analyze(mlir::Value ref1, mlir::Value ref2) { if (ref1 == ref2) - return true; + return SlicesOverlapKind::DefinitelyIdentical; auto des1 = ref1.getDefiningOp(); auto des2 = ref2.getDefiningOp(); // We only support a pair of designators right now. if (!des1 || !des2) - return false; + return SlicesOverlapKind::Unknown; if (des1.getMemref() != des2.getMemref()) { // If the bases are different, then there is unknown overlap. LLVM_DEBUG(llvm::dbgs() << "No identical base for:\n" << des1 << "and:\n" << des2 << "\n"); - return false; + return SlicesOverlapKind::Unknown; } // Require all components of the designators to be the same. @@ -194,104 +328,105 @@ static bool areIdenticalOrDisjointSlices(mlir::Value ref1, mlir::Value ref2) { LLVM_DEBUG(llvm::dbgs() << "Different designator specs for:\n" << des1 << "and:\n" << des2 << "\n"); - return false; - } - - if (des1.getIsTriplet() != des2.getIsTriplet()) { - LLVM_DEBUG(llvm::dbgs() << "Different sections for:\n" - << des1 << "and:\n" - << des2 << "\n"); - return false; + return SlicesOverlapKind::Unknown; } // Analyze the subscripts. - // For example: - // hlfir.designate %6#0 (%c2:%c7999:%c1, %c1:%c120:%c1, %0) shape %9 - // hlfir.designate %6#0 (%c2:%c7999:%c1, %c1:%c120:%c1, %1) shape %9 - // - // If all the triplets (section speficiers) are the same, then - // we do not care if %0 is equal to %1 - the slices are either - // identical or completely disjoint. auto des1It = des1.getIndices().begin(); auto des2It = des2.getIndices().begin(); bool identicalTriplets = true; - for (bool isTriplet : des1.getIsTriplet()) { - if (isTriplet) { - for (int i = 0; i < 3; ++i) - if (*des1It++ != *des2It++) { - LLVM_DEBUG(llvm::dbgs() << "Triplet mismatch for:\n" - << des1 << "and:\n" - << des2 << "\n"); - identicalTriplets = false; - break; - } - } else { - ++des1It; - ++des2It; + bool identicalIndices = true; + for (auto [isTriplet1, isTriplet2] : + llvm::zip(des1.getIsTriplet(), des2.getIsTriplet())) { + SectionDesc desc1 = readSectionDesc(des1It, isTriplet1); + SectionDesc desc2 = readSectionDesc(des2It, isTriplet2); + + // See if we can prove that any of the sections do not overlap. + // This is mostly a Polyhedron/nf performance hack that looks for + // particular relations between the lower and upper bounds + // of the array sections, e.g. for any positive constant C: + // X:Y does not overlap with (Y+C):Z + // X:Y does not overlap with Z:(X-C) + if (areDisjointSections(desc1, desc2)) + return SlicesOverlapKind::DefinitelyDisjoint; + + if (!areIdenticalSections(desc1, desc2)) { + if (isTriplet1 || isTriplet2) { + // For example: + // hlfir.designate %6#0 (%c2:%c7999:%c1, %c1:%c120:%c1, %0) + // hlfir.designate %6#0 (%c2:%c7999:%c1, %c1:%c120:%c1, %1) + // + // If all the triplets (section speficiers) are the same, then + // we do not care if %0 is equal to %1 - the slices are either + // identical or completely disjoint. + // + // Also, treat these as identical sections: + // hlfir.designate %6#0 (%c2:%c2:%c1) + // hlfir.designate %6#0 (%c2) + identicalTriplets = false; + LLVM_DEBUG(llvm::dbgs() << "Triplet mismatch for:\n" + << des1 << "and:\n" + << des2 << "\n"); + } else { + identicalIndices = false; + LLVM_DEBUG(llvm::dbgs() << "Indices mismatch for:\n" + << des1 << "and:\n" + << des2 << "\n"); + } } } - if (identicalTriplets) - return true; - // See if we can prove that any of the triplets do not overlap. - // This is mostly a Polyhedron/nf performance hack that looks for - // particular relations between the lower and upper bounds - // of the array sections, e.g. for any positive constant C: - // X:Y does not overlap with (Y+C):Z - // X:Y does not overlap with Z:(X-C) - auto displacedByConstant = [](mlir::Value v1, mlir::Value v2) { - auto removeConvert = [](mlir::Value v) -> mlir::Operation * { - auto *op = v.getDefiningOp(); - while (auto conv = mlir::dyn_cast_or_null(op)) - op = conv.getValue().getDefiningOp(); - return op; - }; + if (identicalTriplets) { + if (identicalIndices) + return SlicesOverlapKind::DefinitelyIdentical; + else + return SlicesOverlapKind::EitherIdenticalOrDisjoint; + } - auto isPositiveConstant = [](mlir::Value v) -> bool { - if (auto conOp = - mlir::dyn_cast(v.getDefiningOp())) - if (auto iattr = mlir::dyn_cast(conOp.getValue())) - return iattr.getInt() > 0; - return false; - }; + LLVM_DEBUG(llvm::dbgs() << "Different sections for:\n" + << des1 << "and:\n" + << des2 << "\n"); + return SlicesOverlapKind::Unknown; +} - auto *op1 = removeConvert(v1); - auto *op2 = removeConvert(v2); - if (!op1 || !op2) - return false; - if (auto addi = mlir::dyn_cast(op2)) - if ((addi.getLhs().getDefiningOp() == op1 && - isPositiveConstant(addi.getRhs())) || - (addi.getRhs().getDefiningOp() == op1 && - isPositiveConstant(addi.getLhs()))) - return true; - if (auto subi = mlir::dyn_cast(op1)) - if (subi.getLhs().getDefiningOp() == op2 && - isPositiveConstant(subi.getRhs())) - return true; +bool ArraySectionAnalyzer::isLess(mlir::Value v1, mlir::Value v2) { + auto removeConvert = [](mlir::Value v) -> mlir::Operation * { + auto *op = v.getDefiningOp(); + while (auto conv = mlir::dyn_cast_or_null(op)) + op = conv.getValue().getDefiningOp(); + return op; + }; + + auto isPositiveConstant = [](mlir::Value v) -> bool { + if (auto val = fir::getIntIfConstant(v)) + return *val > 0; return false; }; - des1It = des1.getIndices().begin(); - des2It = des2.getIndices().begin(); - for (bool isTriplet : des1.getIsTriplet()) { - if (isTriplet) { - mlir::Value des1Lb = *des1It++; - mlir::Value des1Ub = *des1It++; - mlir::Value des2Lb = *des2It++; - mlir::Value des2Ub = *des2It++; - // Ignore strides. - ++des1It; - ++des2It; - if (displacedByConstant(des1Ub, des2Lb) || - displacedByConstant(des2Ub, des1Lb)) - return true; - } else { - ++des1It; - ++des2It; - } - } + auto *op1 = removeConvert(v1); + auto *op2 = removeConvert(v2); + if (!op1 || !op2) + return false; + // Check if they are both constants. + if (auto val1 = fir::getIntIfConstant(op1->getResult(0))) + if (auto val2 = fir::getIntIfConstant(op2->getResult(0))) + return *val1 < *val2; + + // Handle some variable cases (C > 0): + // v2 = v1 + C + // v2 = C + v1 + // v1 = v2 - C + if (auto addi = mlir::dyn_cast(op2)) + if ((addi.getLhs().getDefiningOp() == op1 && + isPositiveConstant(addi.getRhs())) || + (addi.getRhs().getDefiningOp() == op1 && + isPositiveConstant(addi.getLhs()))) + return true; + if (auto subi = mlir::dyn_cast(op1)) + if (subi.getLhs().getDefiningOp() == op2 && + isPositiveConstant(subi.getRhs())) + return true; return false; } @@ -328,44 +463,36 @@ ElementalAssignBufferization::findMatch(hlfir::ElementalOp elemental) { match.array = match.assign.getLhs(); mlir::Type arrayType = mlir::dyn_cast( fir::unwrapPassByRefType(match.array.getType())); - if (!arrayType) + if (!arrayType) { + LLVM_DEBUG(llvm::dbgs() << "AssignOp's result is not an array\n"); return std::nullopt; + } // require that the array elements are trivial // TODO: this is just to make the pass easier to think about. Not an inherent // limitation mlir::Type eleTy = hlfir::getFortranElementType(arrayType); - if (!fir::isa_trivial(eleTy)) + if (!fir::isa_trivial(eleTy)) { + LLVM_DEBUG(llvm::dbgs() << "AssignOp's data type is not trivial\n"); return std::nullopt; + } - // the array must have the same shape as the elemental. CSE should have - // deduplicated the fir.shape operations where they are provably the same - // so we just have to check for the same ssa value - // TODO: add more ways of getting the shape of the array - mlir::Value arrayShape; - if (match.array.getDefiningOp()) - arrayShape = - mlir::TypeSwitch( - match.array.getDefiningOp()) - .Case([](hlfir::DesignateOp designate) { - return designate.getShape(); - }) - .Case([](hlfir::DeclareOp declare) { return declare.getShape(); }) - .Default([](mlir::Operation *) { return mlir::Value{}; }); - if (!arrayShape) { - LLVM_DEBUG(llvm::dbgs() << "Can't get shape of " << match.array << " at " - << elemental->getLoc() << "\n"); + // The array must have the same shape as the elemental. + // + // f2018 10.2.1.2 (3) requires the lhs and rhs of an assignment to be + // conformable unless the lhs is an allocatable array. In HLFIR we can + // see this from the presence or absence of the realloc attribute on + // hlfir.assign. If it is not a realloc assignment, we can trust that + // the shapes do conform. + // + // TODO: the lhs's shape is dynamic, so it is hard to prove that + // there is no reallocation of the lhs due to the assignment. + // We can probably try generating multiple versions of the code + // with checking for the shape match, length parameters match, etc. + if (match.assign.isAllocatableAssignment()) { + LLVM_DEBUG(llvm::dbgs() << "AssignOp may involve (re)allocation of LHS\n"); return std::nullopt; } - if (arrayShape != elemental.getShape()) { - // f2018 10.2.1.2 (3) requires the lhs and rhs of an assignment to be - // conformable unless the lhs is an allocatable array. In HLFIR we can - // see this from the presence or absence of the realloc attribute on - // hlfir.assign. If it is not a realloc assignment, we can trust that - // the shapes do conform - if (match.assign.getRealloc()) - return std::nullopt; - } // the transformation wants to apply the elemental in a do-loop at the // hlfir.assign, check there are no effects which make this unsafe @@ -419,21 +546,27 @@ ElementalAssignBufferization::findMatch(hlfir::ElementalOp elemental) { if (!res.isPartial()) { if (auto designate = effect.getValue().getDefiningOp()) { - if (!areIdenticalOrDisjointSlices(match.array, designate.getMemref())) { + ArraySectionAnalyzer::SlicesOverlapKind overlap = + ArraySectionAnalyzer::analyze(match.array, designate.getMemref()); + if (overlap == + ArraySectionAnalyzer::SlicesOverlapKind::DefinitelyDisjoint) + continue; + + if (overlap == ArraySectionAnalyzer::SlicesOverlapKind::Unknown) { LLVM_DEBUG(llvm::dbgs() << "possible read conflict: " << designate << " at " << elemental.getLoc() << "\n"); return std::nullopt; } auto indices = designate.getIndices(); auto elementalIndices = elemental.getIndices(); - if (indices.size() != elementalIndices.size()) { - LLVM_DEBUG(llvm::dbgs() << "possible read conflict: " << designate - << " at " << elemental.getLoc() << "\n"); - return std::nullopt; - } - if (std::equal(indices.begin(), indices.end(), elementalIndices.begin(), + if (indices.size() == elementalIndices.size() && + std::equal(indices.begin(), indices.end(), elementalIndices.begin(), elementalIndices.end())) continue; + + LLVM_DEBUG(llvm::dbgs() << "possible read conflict: " << designate + << " at " << elemental.getLoc() << "\n"); + return std::nullopt; } } LLVM_DEBUG(llvm::dbgs() << "disallowed side-effect: " << effect.getValue() diff --git a/flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp b/flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp index 60b06437e6a98..28325bc8e5489 100644 --- a/flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp +++ b/flang/lib/Optimizer/HLFIR/Transforms/SimplifyHLFIRIntrinsics.cpp @@ -10,24 +10,29 @@ // into the calling function. //===----------------------------------------------------------------------===// +#include "flang/Optimizer/Builder/Complex.h" #include "flang/Optimizer/Builder/FIRBuilder.h" #include "flang/Optimizer/Builder/HLFIRTools.h" +#include "flang/Optimizer/Builder/IntrinsicCall.h" #include "flang/Optimizer/Dialect/FIRDialect.h" #include "flang/Optimizer/HLFIR/HLFIRDialect.h" #include "flang/Optimizer/HLFIR/HLFIROps.h" #include "flang/Optimizer/HLFIR/Passes.h" #include "mlir/Dialect/Arith/IR/Arith.h" -#include "mlir/Dialect/Func/IR/FuncOps.h" -#include "mlir/IR/BuiltinDialect.h" #include "mlir/IR/Location.h" #include "mlir/Pass/Pass.h" -#include "mlir/Transforms/DialectConversion.h" +#include "mlir/Transforms/GreedyPatternRewriteDriver.h" namespace hlfir { #define GEN_PASS_DEF_SIMPLIFYHLFIRINTRINSICS #include "flang/Optimizer/HLFIR/Passes.h.inc" } // namespace hlfir +static llvm::cl::opt + simplifySum("flang-simplify-hlfir-sum", + llvm::cl::desc("Expand hlfir.sum into an inline sequence"), + llvm::cl::init(true)); + namespace { class TransposeAsElementalConversion @@ -38,9 +43,15 @@ class TransposeAsElementalConversion llvm::LogicalResult matchAndRewrite(hlfir::TransposeOp transpose, mlir::PatternRewriter &rewriter) const override { + hlfir::ExprType expr = transpose.getType(); + // TODO: hlfir.elemental supports polymorphic data types now, + // so this can be supported. + if (expr.isPolymorphic()) + return rewriter.notifyMatchFailure(transpose, + "TRANSPOSE of polymorphic type"); + mlir::Location loc = transpose.getLoc(); fir::FirOpBuilder builder{rewriter, transpose.getOperation()}; - hlfir::ExprType expr = transpose.getType(); mlir::Type elementType = expr.getElementType(); hlfir::Entity array = hlfir::Entity{transpose.getArray()}; mlir::Value resultShape = genResultShape(loc, builder, array); @@ -90,25 +101,398 @@ class TransposeAsElementalConversion } }; +// Expand the SUM(DIM=CONSTANT) operation into . +class SumAsElementalConversion : public mlir::OpRewritePattern { +public: + using mlir::OpRewritePattern::OpRewritePattern; + + llvm::LogicalResult + matchAndRewrite(hlfir::SumOp sum, + mlir::PatternRewriter &rewriter) const override { + if (!simplifySum) + return rewriter.notifyMatchFailure(sum, "SUM simplification is disabled"); + + hlfir::Entity array = hlfir::Entity{sum.getArray()}; + bool isTotalReduction = hlfir::Entity{sum}.getRank() == 0; + mlir::Value dim = sum.getDim(); + int64_t dimVal = 0; + if (!isTotalReduction) { + // In case of partial reduction we should ignore the operations + // with invalid DIM values. They may appear in dead code + // after constant propagation. + auto constDim = fir::getIntIfConstant(dim); + if (!constDim) + return rewriter.notifyMatchFailure(sum, "Nonconstant DIM for SUM"); + dimVal = *constDim; + + if ((dimVal <= 0 || dimVal > array.getRank())) + return rewriter.notifyMatchFailure( + sum, "Invalid DIM for partial SUM reduction"); + } + + mlir::Location loc = sum.getLoc(); + fir::FirOpBuilder builder{rewriter, sum.getOperation()}; + mlir::Type elementType = hlfir::getFortranElementType(sum.getType()); + mlir::Value mask = sum.getMask(); + + mlir::Value resultShape, dimExtent; + llvm::SmallVector arrayExtents; + if (isTotalReduction) + arrayExtents = genArrayExtents(loc, builder, array); + else + std::tie(resultShape, dimExtent) = + genResultShapeForPartialReduction(loc, builder, array, dimVal); + + // If the mask is present and is a scalar, then we'd better load its value + // outside of the reduction loop making the loop unswitching easier. + mlir::Value isPresentPred, maskValue; + if (mask) { + if (mlir::isa(mask.getType())) { + // MASK represented by a box might be dynamically optional, + // so we have to check for its presence before accessing it. + isPresentPred = + builder.create(loc, builder.getI1Type(), mask); + } + + if (hlfir::Entity{mask}.isScalar()) + maskValue = genMaskValue(loc, builder, mask, isPresentPred, {}); + } + + auto genKernel = [&](mlir::Location loc, fir::FirOpBuilder &builder, + mlir::ValueRange inputIndices) -> hlfir::Entity { + // Loop over all indices in the DIM dimension, and reduce all values. + // If DIM is not present, do total reduction. + + // Initial value for the reduction. + mlir::Value reductionInitValue = genInitValue(loc, builder, elementType); + + // The reduction loop may be unordered if FastMathFlags::reassoc + // transformations are allowed. The integer reduction is always + // unordered. + bool isUnordered = mlir::isa(elementType) || + static_cast(sum.getFastmath() & + mlir::arith::FastMathFlags::reassoc); + + llvm::SmallVector extents; + if (isTotalReduction) + extents = arrayExtents; + else + extents.push_back( + builder.createConvert(loc, builder.getIndexType(), dimExtent)); + + auto genBody = [&](mlir::Location loc, fir::FirOpBuilder &builder, + mlir::ValueRange oneBasedIndices, + mlir::ValueRange reductionArgs) + -> llvm::SmallVector { + // Generate the reduction loop-nest body. + // The initial reduction value in the innermost loop + // is passed via reductionArgs[0]. + llvm::SmallVector indices; + if (isTotalReduction) { + indices = oneBasedIndices; + } else { + indices = inputIndices; + indices.insert(indices.begin() + dimVal - 1, oneBasedIndices[0]); + } + + mlir::Value reductionValue = reductionArgs[0]; + fir::IfOp ifOp; + if (mask) { + // Make the reduction value update conditional on the value + // of the mask. + if (!maskValue) { + // If the mask is an array, use the elemental and the loop indices + // to address the proper mask element. + maskValue = + genMaskValue(loc, builder, mask, isPresentPred, indices); + } + mlir::Value isUnmasked = builder.create( + loc, builder.getI1Type(), maskValue); + ifOp = builder.create(loc, elementType, isUnmasked, + /*withElseRegion=*/true); + // In the 'else' block return the current reduction value. + builder.setInsertionPointToStart(&ifOp.getElseRegion().front()); + builder.create(loc, reductionValue); + + // In the 'then' block do the actual addition. + builder.setInsertionPointToStart(&ifOp.getThenRegion().front()); + } + + hlfir::Entity element = + hlfir::getElementAt(loc, builder, array, indices); + hlfir::Entity elementValue = + hlfir::loadTrivialScalar(loc, builder, element); + // NOTE: we can use "Kahan summation" same way as the runtime + // (e.g. when fast-math is not allowed), but let's start with + // the simple version. + reductionValue = + genScalarAdd(loc, builder, reductionValue, elementValue); + + if (ifOp) { + builder.create(loc, reductionValue); + builder.setInsertionPointAfter(ifOp); + reductionValue = ifOp.getResult(0); + } + + return {reductionValue}; + }; + + llvm::SmallVector reductionFinalValues = + hlfir::genLoopNestWithReductions(loc, builder, extents, + {reductionInitValue}, genBody, + isUnordered); + return hlfir::Entity{reductionFinalValues[0]}; + }; + + if (isTotalReduction) { + hlfir::Entity result = genKernel(loc, builder, mlir::ValueRange{}); + rewriter.replaceOp(sum, result); + return mlir::success(); + } + + hlfir::ElementalOp elementalOp = hlfir::genElementalOp( + loc, builder, elementType, resultShape, {}, genKernel, + /*isUnordered=*/true, /*polymorphicMold=*/nullptr, + sum.getResult().getType()); + + // it wouldn't be safe to replace block arguments with a different + // hlfir.expr type. Types can differ due to differing amounts of shape + // information + assert(elementalOp.getResult().getType() == sum.getResult().getType()); + + rewriter.replaceOp(sum, elementalOp); + return mlir::success(); + } + +private: + static llvm::SmallVector + genArrayExtents(mlir::Location loc, fir::FirOpBuilder &builder, + hlfir::Entity array) { + mlir::Value inShape = hlfir::genShape(loc, builder, array); + llvm::SmallVector inExtents = + hlfir::getExplicitExtentsFromShape(inShape, builder); + if (inShape.getUses().empty()) + inShape.getDefiningOp()->erase(); + return inExtents; + } + + // Return fir.shape specifying the shape of the result + // of a SUM reduction with DIM=dimVal. The second return value + // is the extent of the DIM dimension. + static std::tuple + genResultShapeForPartialReduction(mlir::Location loc, + fir::FirOpBuilder &builder, + hlfir::Entity array, int64_t dimVal) { + llvm::SmallVector inExtents = + genArrayExtents(loc, builder, array); + assert(dimVal > 0 && dimVal <= static_cast(inExtents.size()) && + "DIM must be present and a positive constant not exceeding " + "the array's rank"); + + mlir::Value dimExtent = inExtents[dimVal - 1]; + inExtents.erase(inExtents.begin() + dimVal - 1); + return {builder.create(loc, inExtents), dimExtent}; + } + + // Generate the initial value for a SUM reduction with the given + // data type. + static mlir::Value genInitValue(mlir::Location loc, + fir::FirOpBuilder &builder, + mlir::Type elementType) { + if (auto ty = mlir::dyn_cast(elementType)) { + const llvm::fltSemantics &sem = ty.getFloatSemantics(); + return builder.createRealConstant(loc, elementType, + llvm::APFloat::getZero(sem)); + } else if (auto ty = mlir::dyn_cast(elementType)) { + mlir::Value initValue = genInitValue(loc, builder, ty.getElementType()); + return fir::factory::Complex{builder, loc}.createComplex(ty, initValue, + initValue); + } else if (mlir::isa(elementType)) { + return builder.createIntegerConstant(loc, elementType, 0); + } + + llvm_unreachable("unsupported SUM reduction type"); + } + + // Generate scalar addition of the two values (of the same data type). + static mlir::Value genScalarAdd(mlir::Location loc, + fir::FirOpBuilder &builder, + mlir::Value value1, mlir::Value value2) { + mlir::Type ty = value1.getType(); + assert(ty == value2.getType() && "reduction values' types do not match"); + if (mlir::isa(ty)) + return builder.create(loc, value1, value2); + else if (mlir::isa(ty)) + return builder.create(loc, value1, value2); + else if (mlir::isa(ty)) + return builder.create(loc, value1, value2); + + llvm_unreachable("unsupported SUM reduction type"); + } + + static mlir::Value genMaskValue(mlir::Location loc, + fir::FirOpBuilder &builder, mlir::Value mask, + mlir::Value isPresentPred, + mlir::ValueRange indices) { + mlir::OpBuilder::InsertionGuard guard(builder); + fir::IfOp ifOp; + mlir::Type maskType = + hlfir::getFortranElementType(fir::unwrapPassByRefType(mask.getType())); + if (isPresentPred) { + ifOp = builder.create(loc, maskType, isPresentPred, + /*withElseRegion=*/true); + + // Use 'true', if the mask is not present. + builder.setInsertionPointToStart(&ifOp.getElseRegion().front()); + mlir::Value trueValue = builder.createBool(loc, true); + trueValue = builder.createConvert(loc, maskType, trueValue); + builder.create(loc, trueValue); + + // Load the mask value, if the mask is present. + builder.setInsertionPointToStart(&ifOp.getThenRegion().front()); + } + + hlfir::Entity maskVar{mask}; + if (maskVar.isScalar()) { + if (mlir::isa(mask.getType())) { + // MASK may be a boxed scalar. + mlir::Value addr = hlfir::genVariableRawAddress(loc, builder, maskVar); + mask = builder.create(loc, hlfir::Entity{addr}); + } else { + mask = hlfir::loadTrivialScalar(loc, builder, maskVar); + } + } else { + // Load from the mask array. + assert(!indices.empty() && "no indices for addressing the mask array"); + maskVar = hlfir::getElementAt(loc, builder, maskVar, indices); + mask = hlfir::loadTrivialScalar(loc, builder, maskVar); + } + + if (!isPresentPred) + return mask; + + builder.create(loc, mask); + return ifOp.getResult(0); + } +}; + +class CShiftAsElementalConversion + : public mlir::OpRewritePattern { +public: + using mlir::OpRewritePattern::OpRewritePattern; + + llvm::LogicalResult + matchAndRewrite(hlfir::CShiftOp cshift, + mlir::PatternRewriter &rewriter) const override { + using Fortran::common::maxRank; + + hlfir::ExprType expr = mlir::dyn_cast(cshift.getType()); + assert(expr && + "expected an expression type for the result of hlfir.cshift"); + unsigned arrayRank = expr.getRank(); + // When it is a 1D CSHIFT, we may assume that the DIM argument + // (whether it is present or absent) is equal to 1, otherwise, + // the program is illegal. + int64_t dimVal = 1; + if (arrayRank != 1) + if (mlir::Value dim = cshift.getDim()) { + auto constDim = fir::getIntIfConstant(dim); + if (!constDim) + return rewriter.notifyMatchFailure(cshift, + "Nonconstant DIM for CSHIFT"); + dimVal = *constDim; + } + + if (dimVal <= 0 || dimVal > arrayRank) + return rewriter.notifyMatchFailure(cshift, "Invalid DIM for CSHIFT"); + + mlir::Location loc = cshift.getLoc(); + fir::FirOpBuilder builder{rewriter, cshift.getOperation()}; + mlir::Type elementType = expr.getElementType(); + hlfir::Entity array = hlfir::Entity{cshift.getArray()}; + mlir::Value arrayShape = hlfir::genShape(loc, builder, array); + llvm::SmallVector arrayExtents = + hlfir::getExplicitExtentsFromShape(arrayShape, builder); + llvm::SmallVector typeParams; + hlfir::genLengthParameters(loc, builder, array, typeParams); + hlfir::Entity shift = hlfir::Entity{cshift.getShift()}; + // The new index computation involves MODULO, which is not implemented + // for IndexType, so use I64 instead. + mlir::Type calcType = builder.getI64Type(); + + mlir::Value one = builder.createIntegerConstant(loc, calcType, 1); + mlir::Value shiftVal; + if (shift.isScalar()) { + shiftVal = hlfir::loadTrivialScalar(loc, builder, shift); + shiftVal = builder.createConvert(loc, calcType, shiftVal); + } + + auto genKernel = [&](mlir::Location loc, fir::FirOpBuilder &builder, + mlir::ValueRange inputIndices) -> hlfir::Entity { + llvm::SmallVector indices{inputIndices}; + if (!shift.isScalar()) { + // When the array is not a vector, section + // (s(1), s(2), ..., s(dim-1), :, s(dim+1), ..., s(n) + // of the result has a value equal to: + // CSHIFT(ARRAY(s(1), s(2), ..., s(dim-1), :, s(dim+1), ..., s(n)), + // SH, 1), + // where SH is either SHIFT (if scalar) or + // SHIFT(s(1), s(2), ..., s(dim-1), s(dim+1), ..., s(n)). + llvm::SmallVector shiftIndices{indices}; + shiftIndices.erase(shiftIndices.begin() + dimVal - 1); + hlfir::Entity shiftElement = + hlfir::getElementAt(loc, builder, shift, shiftIndices); + shiftVal = hlfir::loadTrivialScalar(loc, builder, shiftElement); + shiftVal = builder.createConvert(loc, calcType, shiftVal); + } + + // Element i of the result (1-based) is element + // 'MODULO(i + SH - 1, SIZE(ARRAY)) + 1' (1-based) of the original + // ARRAY (or its section, when ARRAY is not a vector). + mlir::Value index = + builder.createConvert(loc, calcType, inputIndices[dimVal - 1]); + mlir::Value extent = arrayExtents[dimVal - 1]; + mlir::Value newIndex = + builder.create(loc, index, shiftVal); + newIndex = builder.create(loc, newIndex, one); + newIndex = fir::IntrinsicLibrary{builder, loc}.genModulo( + calcType, {newIndex, builder.createConvert(loc, calcType, extent)}); + newIndex = builder.create(loc, newIndex, one); + newIndex = builder.createConvert(loc, builder.getIndexType(), newIndex); + + indices[dimVal - 1] = newIndex; + hlfir::Entity element = hlfir::getElementAt(loc, builder, array, indices); + return hlfir::loadTrivialScalar(loc, builder, element); + }; + + hlfir::ElementalOp elementalOp = hlfir::genElementalOp( + loc, builder, elementType, arrayShape, typeParams, genKernel, + /*isUnordered=*/true, + array.isPolymorphic() ? static_cast(array) : nullptr, + cshift.getResult().getType()); + rewriter.replaceOp(cshift, elementalOp); + return mlir::success(); + } +}; + class SimplifyHLFIRIntrinsics : public hlfir::impl::SimplifyHLFIRIntrinsicsBase { public: void runOnOperation() override { mlir::MLIRContext *context = &getContext(); + + mlir::GreedyRewriteConfig config; + // Prevent the pattern driver from merging blocks + config.enableRegionSimplification = + mlir::GreedySimplifyRegionLevel::Disabled; + mlir::RewritePatternSet patterns(context); patterns.insert(context); - mlir::ConversionTarget target(*context); - // don't transform transpose of polymorphic arrays (not currently supported - // by hlfir.elemental) - target.addDynamicallyLegalOp( - [](hlfir::TransposeOp transpose) { - return mlir::cast(transpose.getType()) - .isPolymorphic(); - }); - target.markUnknownOpDynamicallyLegal( - [](mlir::Operation *) { return true; }); - if (mlir::failed(mlir::applyFullConversion(getOperation(), target, - std::move(patterns)))) { + patterns.insert(context); + patterns.insert(context); + + if (mlir::failed(mlir::applyPatternsAndFoldGreedily( + getOperation(), std::move(patterns), config))) { mlir::emitError(getOperation()->getLoc(), "failure in HLFIR intrinsic simplification"); signalPassFailure(); diff --git a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp index d2c814cc958dd..c990bebcabde4 100644 --- a/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp +++ b/flang/lib/Optimizer/OpenMP/MapsForPrivatizedSymbols.cpp @@ -49,13 +49,6 @@ class MapsForPrivatizedSymbolsPass : public flangomp::impl::MapsForPrivatizedSymbolsPassBase< MapsForPrivatizedSymbolsPass> { - bool privatizerNeedsMap(omp::PrivateClauseOp &privatizer) { - Region &allocRegion = privatizer.getAllocRegion(); - Value blockArg0 = allocRegion.getArgument(0); - if (blockArg0.use_empty()) - return false; - return true; - } omp::MapInfoOp createMapInfo(Location loc, Value var, fir::FirOpBuilder &builder) { uint64_t mapTypeTo = static_cast< @@ -134,7 +127,7 @@ class MapsForPrivatizedSymbolsPass omp::PrivateClauseOp privatizer = SymbolTable::lookupNearestSymbolFrom( targetOp, privatizerName); - if (!privatizerNeedsMap(privatizer)) { + if (!privatizer.needsMap()) { privVarMapIdx.push_back(-1); continue; } diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp index 4855dd401ac60..a9a264b88eb51 100644 --- a/flang/lib/Optimizer/Passes/Pipelines.cpp +++ b/flang/lib/Optimizer/Passes/Pipelines.cpp @@ -13,18 +13,24 @@ namespace fir { -void addNestedPassToAllTopLevelOperations(mlir::PassManager &pm, - PassConstructor ctor) { - addNestedPassToOps(pm, ctor); +template +void addNestedPassToAllTopLevelOperations(mlir::PassManager &pm, F ctor) { + addNestedPassToOps(pm, ctor); } +template +void addPassToGPUModuleOperations(mlir::PassManager &pm, F ctor) { + mlir::OpPassManager &nestPM = pm.nest(); + nestPM.addNestedPass(ctor()); + nestPM.addNestedPass(ctor()); +} + +template void addNestedPassToAllTopLevelOperationsConditionally( - mlir::PassManager &pm, llvm::cl::opt &disabled, - PassConstructor ctor) { + mlir::PassManager &pm, llvm::cl::opt &disabled, F ctor) { if (!disabled) - addNestedPassToAllTopLevelOperations(pm, ctor); + addNestedPassToAllTopLevelOperations(pm, ctor); } void addCanonicalizerPassWithoutRegionSimplification(mlir::OpPassManager &pm) { @@ -35,12 +41,11 @@ void addCanonicalizerPassWithoutRegionSimplification(mlir::OpPassManager &pm) { void addCfgConversionPass(mlir::PassManager &pm, const MLIRToLLVMPassPipelineConfig &config) { - if (config.NSWOnLoopVarInc) - addNestedPassToAllTopLevelOperationsConditionally( - pm, disableCfgConversion, fir::createCFGConversionPassWithNSW); - else - addNestedPassToAllTopLevelOperationsConditionally(pm, disableCfgConversion, - fir::createCFGConversion); + fir::CFGConversionOptions options; + if (!config.NSWOnLoopVarInc) + options.setNSW = false; + addNestedPassToAllTopLevelOperationsConditionally( + pm, disableCfgConversion, [&]() { return createCFGConversion(options); }); } void addAVC(mlir::PassManager &pm, const llvm::OptimizationLevel &optLevel) { @@ -161,7 +166,8 @@ void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm, config.enableRegionSimplification = mlir::GreedySimplifyRegionLevel::Disabled; pm.addPass(mlir::createCSEPass()); fir::addAVC(pm, pc.OptLevel); - addNestedPassToAllTopLevelOperations(pm, fir::createCharacterConversion); + addNestedPassToAllTopLevelOperations( + pm, fir::createCharacterConversion); pm.addPass(mlir::createCanonicalizerPass(config)); pm.addPass(fir::createSimplifyRegionLite()); if (pc.OptLevel.isOptimizingForSpeed()) { @@ -195,7 +201,8 @@ void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm, if (pc.AliasAnalysis && !disableFirAliasTags && !useOldAliasTags) pm.addPass(fir::createAddAliasTags()); - addNestedPassToAllTopLevelOperations(pm, fir::createStackReclaim); + addNestedPassToAllTopLevelOperations( + pm, fir::createStackReclaim); // convert control flow to CFG form fir::addCfgConversionPass(pm, pc); pm.addPass(mlir::createConvertSCFToCFPass()); @@ -217,15 +224,16 @@ void createHLFIRToFIRPassPipeline(mlir::PassManager &pm, bool enableOpenMP, llvm::OptimizationLevel optLevel) { if (optLevel.isOptimizingForSpeed()) { addCanonicalizerPassWithoutRegionSimplification(pm); - addNestedPassToAllTopLevelOperations(pm, - hlfir::createSimplifyHLFIRIntrinsics); + addNestedPassToAllTopLevelOperations( + pm, hlfir::createSimplifyHLFIRIntrinsics); } - addNestedPassToAllTopLevelOperations(pm, hlfir::createInlineElementals); + addNestedPassToAllTopLevelOperations( + pm, hlfir::createInlineElementals); if (optLevel.isOptimizingForSpeed()) { addCanonicalizerPassWithoutRegionSimplification(pm); pm.addPass(mlir::createCSEPass()); - addNestedPassToAllTopLevelOperations(pm, - hlfir::createOptimizedBufferization); + addNestedPassToAllTopLevelOperations( + pm, hlfir::createOptimizedBufferization); } pm.addPass(hlfir::createLowerHLFIROrderedAssignments()); pm.addPass(hlfir::createLowerHLFIRIntrinsics()); @@ -274,7 +282,10 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, MLIRToLLVMPassPipelineConfig config, llvm::StringRef inputFilename) { fir::addBoxedProcedurePass(pm); - addNestedPassToAllTopLevelOperations(pm, fir::createAbstractResultOpt); + addNestedPassToAllTopLevelOperations( + pm, fir::createAbstractResultOpt); + addPassToGPUModuleOperations(pm, + fir::createAbstractResultOpt); fir::addCodeGenRewritePass( pm, (config.DebugInfo != llvm::codegenoptions::NoDebugInfo)); fir::addExternalNameConversionPass(pm, config.Underscoring); diff --git a/flang/lib/Optimizer/Transforms/AbstractResult.cpp b/flang/lib/Optimizer/Transforms/AbstractResult.cpp index 2eca349110f3a..b0327cc10e9de 100644 --- a/flang/lib/Optimizer/Transforms/AbstractResult.cpp +++ b/flang/lib/Optimizer/Transforms/AbstractResult.cpp @@ -234,6 +234,60 @@ class SaveResultOpConversion } }; +template +static mlir::LogicalResult +processReturnLikeOp(OpTy ret, mlir::Value newArg, + mlir::PatternRewriter &rewriter) { + auto loc = ret.getLoc(); + rewriter.setInsertionPoint(ret); + mlir::Value resultValue = ret.getOperand(0); + fir::LoadOp resultLoad; + mlir::Value resultStorage; + // Identify result local storage. + if (auto load = resultValue.getDefiningOp()) { + resultLoad = load; + resultStorage = load.getMemref(); + // The result alloca may be behind a fir.declare, if any. + if (auto declare = resultStorage.getDefiningOp()) + resultStorage = declare.getMemref(); + } + // Replace old local storage with new storage argument, unless + // the derived type is C_PTR/C_FUN_PTR, in which case the return + // type is updated to return void* (no new argument is passed). + if (fir::isa_builtin_cptr_type(resultValue.getType())) { + auto module = ret->template getParentOfType(); + FirOpBuilder builder(rewriter, module); + mlir::Value cptr = resultValue; + if (resultLoad) { + // Replace whole derived type load by component load. + cptr = resultLoad.getMemref(); + rewriter.setInsertionPoint(resultLoad); + } + mlir::Value newResultValue = + fir::factory::genCPtrOrCFunptrValue(builder, loc, cptr); + newResultValue = builder.createConvert( + loc, getVoidPtrType(ret.getContext()), newResultValue); + rewriter.setInsertionPoint(ret); + rewriter.replaceOpWithNewOp(ret, mlir::ValueRange{newResultValue}); + } else if (resultStorage) { + resultStorage.replaceAllUsesWith(newArg); + rewriter.replaceOpWithNewOp(ret); + } else { + // The result storage may have been optimized out by a memory to + // register pass, this is possible for fir.box results, or fir.record + // with no length parameters. Simply store the result in the result + // storage. at the return point. + rewriter.create(loc, resultValue, newArg); + rewriter.replaceOpWithNewOp(ret); + } + // Delete result old local storage if unused. + if (resultStorage) + if (auto alloc = resultStorage.getDefiningOp()) + if (alloc->use_empty()) + rewriter.eraseOp(alloc); + return mlir::success(); +} + class ReturnOpConversion : public mlir::OpRewritePattern { public: using OpRewritePattern::OpRewritePattern; @@ -242,55 +296,23 @@ class ReturnOpConversion : public mlir::OpRewritePattern { llvm::LogicalResult matchAndRewrite(mlir::func::ReturnOp ret, mlir::PatternRewriter &rewriter) const override { - auto loc = ret.getLoc(); - rewriter.setInsertionPoint(ret); - mlir::Value resultValue = ret.getOperand(0); - fir::LoadOp resultLoad; - mlir::Value resultStorage; - // Identify result local storage. - if (auto load = resultValue.getDefiningOp()) { - resultLoad = load; - resultStorage = load.getMemref(); - // The result alloca may be behind a fir.declare, if any. - if (auto declare = resultStorage.getDefiningOp()) - resultStorage = declare.getMemref(); - } - // Replace old local storage with new storage argument, unless - // the derived type is C_PTR/C_FUN_PTR, in which case the return - // type is updated to return void* (no new argument is passed). - if (fir::isa_builtin_cptr_type(resultValue.getType())) { - auto module = ret->getParentOfType(); - FirOpBuilder builder(rewriter, module); - mlir::Value cptr = resultValue; - if (resultLoad) { - // Replace whole derived type load by component load. - cptr = resultLoad.getMemref(); - rewriter.setInsertionPoint(resultLoad); - } - mlir::Value newResultValue = - fir::factory::genCPtrOrCFunptrValue(builder, loc, cptr); - newResultValue = builder.createConvert( - loc, getVoidPtrType(ret.getContext()), newResultValue); - rewriter.setInsertionPoint(ret); - rewriter.replaceOpWithNewOp( - ret, mlir::ValueRange{newResultValue}); - } else if (resultStorage) { - resultStorage.replaceAllUsesWith(newArg); - rewriter.replaceOpWithNewOp(ret); - } else { - // The result storage may have been optimized out by a memory to - // register pass, this is possible for fir.box results, or fir.record - // with no length parameters. Simply store the result in the result - // storage. at the return point. - rewriter.create(loc, resultValue, newArg); - rewriter.replaceOpWithNewOp(ret); - } - // Delete result old local storage if unused. - if (resultStorage) - if (auto alloc = resultStorage.getDefiningOp()) - if (alloc->use_empty()) - rewriter.eraseOp(alloc); - return mlir::success(); + return processReturnLikeOp(ret, newArg, rewriter); + } + +private: + mlir::Value newArg; +}; + +class GPUReturnOpConversion + : public mlir::OpRewritePattern { +public: + using OpRewritePattern::OpRewritePattern; + GPUReturnOpConversion(mlir::MLIRContext *context, mlir::Value newArg) + : OpRewritePattern(context), newArg{newArg} {} + llvm::LogicalResult + matchAndRewrite(mlir::gpu::ReturnOp ret, + mlir::PatternRewriter &rewriter) const override { + return processReturnLikeOp(ret, newArg, rewriter); } private: @@ -373,6 +395,9 @@ class AbstractResultOpt patterns.insert(context, newArg); target.addDynamicallyLegalOp( [](mlir::func::ReturnOp ret) { return ret.getOperands().empty(); }); + patterns.insert(context, newArg); + target.addDynamicallyLegalOp( + [](mlir::gpu::ReturnOp ret) { return ret.getOperands().empty(); }); assert(func.getFunctionType() == getNewFunctionType(funcTy, shouldBoxResult)); } else { @@ -460,17 +485,10 @@ class AbstractResultOpt const bool shouldBoxResult = this->passResultAsBox.getValue(); mlir::TypeSwitch(op) - .Case([&](auto op) { - runOnSpecificOperation(op, shouldBoxResult, patterns, target); - }) - .Case([&](auto op) { - auto gpuMod = mlir::dyn_cast(*op); - for (auto funcOp : gpuMod.template getOps()) - runOnSpecificOperation(funcOp, shouldBoxResult, patterns, target); - for (auto gpuFuncOp : gpuMod.template getOps()) - runOnSpecificOperation(gpuFuncOp, shouldBoxResult, patterns, - target); - }); + .Case( + [&](auto op) { + runOnSpecificOperation(op, shouldBoxResult, patterns, target); + }); // Convert the calls and, if needed, the ReturnOp in the function body. target.addLegalDialect( loc, builder); auto fTy = func.getFunctionType(); diff --git a/flang/lib/Optimizer/Transforms/CUFCommon.cpp b/flang/lib/Optimizer/Transforms/CUFCommon.cpp index 5b7631bbacb5f..bbe33217e8f45 100644 --- a/flang/lib/Optimizer/Transforms/CUFCommon.cpp +++ b/flang/lib/Optimizer/Transforms/CUFCommon.cpp @@ -43,3 +43,14 @@ bool cuf::isInCUDADeviceContext(mlir::Operation *op) { } return false; } + +bool cuf::isRegisteredDeviceGlobal(fir::GlobalOp op) { + if (op.getConstant()) + return false; + auto attr = op.getDataAttr(); + if (attr && (*attr == cuf::DataAttribute::Device || + *attr == cuf::DataAttribute::Managed || + *attr == cuf::DataAttribute::Constant)) + return true; + return false; +} diff --git a/flang/lib/Optimizer/Transforms/CUFDeviceGlobal.cpp b/flang/lib/Optimizer/Transforms/CUFDeviceGlobal.cpp index 714b0b291be1e..07cc1f3b4b51c 100644 --- a/flang/lib/Optimizer/Transforms/CUFDeviceGlobal.cpp +++ b/flang/lib/Optimizer/Transforms/CUFDeviceGlobal.cpp @@ -11,6 +11,7 @@ #include "flang/Optimizer/Dialect/FIRDialect.h" #include "flang/Optimizer/Dialect/FIROps.h" #include "flang/Optimizer/HLFIR/HLFIROps.h" +#include "flang/Optimizer/Support/InternalNames.h" #include "flang/Optimizer/Transforms/CUFCommon.h" #include "flang/Runtime/CUDA/common.h" #include "flang/Runtime/allocatable.h" @@ -18,6 +19,7 @@ #include "mlir/IR/SymbolTable.h" #include "mlir/Pass/Pass.h" #include "mlir/Transforms/DialectConversion.h" +#include "llvm/ADT/DenseSet.h" namespace fir { #define GEN_PASS_DEF_CUFDEVICEGLOBAL @@ -27,36 +29,53 @@ namespace fir { namespace { static void processAddrOfOp(fir::AddrOfOp addrOfOp, - mlir::SymbolTable &symbolTable, bool onlyConstant) { + mlir::SymbolTable &symbolTable, + llvm::DenseSet &candidates, + bool recurseInGlobal) { if (auto globalOp = symbolTable.lookup( addrOfOp.getSymbol().getRootReference().getValue())) { - bool isCandidate{(onlyConstant ? globalOp.getConstant() : true) && - !globalOp.getDataAttr()}; - if (isCandidate) - globalOp.setDataAttrAttr(cuf::DataAttributeAttr::get( - addrOfOp.getContext(), globalOp.getConstant() - ? cuf::DataAttribute::Constant - : cuf::DataAttribute::Device)); + // TO DO: limit candidates to non-scalars. Scalars appear to have been + // folded in already. + if (globalOp.getConstant()) { + if (recurseInGlobal) + globalOp.walk([&](fir::AddrOfOp op) { + processAddrOfOp(op, symbolTable, candidates, recurseInGlobal); + }); + candidates.insert(globalOp); + } + } +} + +static void processEmboxOp(fir::EmboxOp emboxOp, mlir::SymbolTable &symbolTable, + llvm::DenseSet &candidates) { + if (auto recTy = mlir::dyn_cast( + fir::unwrapRefType(emboxOp.getMemref().getType()))) { + if (auto globalOp = symbolTable.lookup( + fir::NameUniquer::getTypeDescriptorName(recTy.getName()))) { + if (!candidates.contains(globalOp)) { + globalOp.walk([&](fir::AddrOfOp op) { + processAddrOfOp(op, symbolTable, candidates, + /*recurseInGlobal=*/true); + }); + candidates.insert(globalOp); + } + } } } -static void prepareImplicitDeviceGlobals(mlir::func::FuncOp funcOp, - mlir::SymbolTable &symbolTable, - bool onlyConstant = true) { +static void +prepareImplicitDeviceGlobals(mlir::func::FuncOp funcOp, + mlir::SymbolTable &symbolTable, + llvm::DenseSet &candidates) { auto cudaProcAttr{ funcOp->getAttrOfType(cuf::getProcAttrName())}; - if (!cudaProcAttr || cudaProcAttr.getValue() == cuf::ProcAttribute::Host) { - // Look for globlas in CUF KERNEL DO operations. - for (auto cufKernelOp : funcOp.getBody().getOps()) { - cufKernelOp.walk([&](fir::AddrOfOp addrOfOp) { - processAddrOfOp(addrOfOp, symbolTable, onlyConstant); - }); - } - return; + if (cudaProcAttr && cudaProcAttr.getValue() != cuf::ProcAttribute::Host) { + funcOp.walk([&](fir::AddrOfOp op) { + processAddrOfOp(op, symbolTable, candidates, /*recurseInGlobal=*/false); + }); + funcOp.walk( + [&](fir::EmboxOp op) { processEmboxOp(op, symbolTable, candidates); }); } - funcOp.walk([&](fir::AddrOfOp addrOfOp) { - processAddrOfOp(addrOfOp, symbolTable, onlyConstant); - }); } class CUFDeviceGlobal : public fir::impl::CUFDeviceGlobalBase { @@ -67,11 +86,18 @@ class CUFDeviceGlobal : public fir::impl::CUFDeviceGlobalBase { if (!mod) return signalPassFailure(); + llvm::DenseSet candidates; mlir::SymbolTable symTable(mod); mod.walk([&](mlir::func::FuncOp funcOp) { - prepareImplicitDeviceGlobals(funcOp, symTable); + prepareImplicitDeviceGlobals(funcOp, symTable, candidates); return mlir::WalkResult::advance(); }); + mod.walk([&](cuf::KernelOp kernelOp) { + kernelOp.walk([&](fir::AddrOfOp addrOfOp) { + processAddrOfOp(addrOfOp, symTable, candidates, + /*recurseInGlobal=*/false); + }); + }); // Copying the device global variable into the gpu module mlir::SymbolTable parentSymTable(mod); @@ -80,22 +106,15 @@ class CUFDeviceGlobal : public fir::impl::CUFDeviceGlobalBase { return signalPassFailure(); mlir::SymbolTable gpuSymTable(gpuMod); for (auto globalOp : mod.getOps()) { - auto attr = globalOp.getDataAttrAttr(); - if (!attr) - continue; - switch (attr.getValue()) { - case cuf::DataAttribute::Device: - case cuf::DataAttribute::Constant: - case cuf::DataAttribute::Managed: { - auto globalName{globalOp.getSymbol().getValue()}; - if (gpuSymTable.lookup(globalName)) { - break; - } - gpuSymTable.insert(globalOp->clone()); - } break; - default: + if (cuf::isRegisteredDeviceGlobal(globalOp)) + candidates.insert(globalOp); + } + for (auto globalOp : candidates) { + auto globalName{globalOp.getSymbol().getValue()}; + if (gpuSymTable.lookup(globalName)) { break; } + gpuSymTable.insert(globalOp->clone()); } } }; diff --git a/flang/lib/Optimizer/Transforms/CUFGPUToLLVMConversion.cpp b/flang/lib/Optimizer/Transforms/CUFGPUToLLVMConversion.cpp index c64f35542a6e5..60aa401e1cc8c 100644 --- a/flang/lib/Optimizer/Transforms/CUFGPUToLLVMConversion.cpp +++ b/flang/lib/Optimizer/Transforms/CUFGPUToLLVMConversion.cpp @@ -42,6 +42,8 @@ static mlir::Value createKernelArgArray(mlir::Location loc, auto structTy = mlir::LLVM::LLVMStructType::getLiteral(ctx, structTypes); auto ptrTy = mlir::LLVM::LLVMPointerType::get(rewriter.getContext()); mlir::Type i32Ty = rewriter.getI32Type(); + auto zero = rewriter.create( + loc, i32Ty, rewriter.getIntegerAttr(i32Ty, 0)); auto one = rewriter.create( loc, i32Ty, rewriter.getIntegerAttr(i32Ty, 1)); mlir::Value argStruct = @@ -55,10 +57,11 @@ static mlir::Value createKernelArgArray(mlir::Location loc, auto indice = rewriter.create( loc, i32Ty, rewriter.getIntegerAttr(i32Ty, i)); mlir::Value structMember = rewriter.create( - loc, ptrTy, structTy, argStruct, mlir::ArrayRef({indice})); + loc, ptrTy, structTy, argStruct, + mlir::ArrayRef({zero, indice})); rewriter.create(loc, arg, structMember); mlir::Value arrayMember = rewriter.create( - loc, ptrTy, structTy, argArray, mlir::ArrayRef({indice})); + loc, ptrTy, ptrTy, argArray, mlir::ArrayRef({indice})); rewriter.create(loc, structMember, arrayMember); } return argArray; diff --git a/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp b/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp index 7f6843d66d39f..1df82e6accfed 100644 --- a/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp +++ b/flang/lib/Optimizer/Transforms/CUFOpConversion.cpp @@ -81,15 +81,6 @@ static bool hasDoubleDescriptors(OpTy op) { return false; } -bool isDeviceGlobal(fir::GlobalOp op) { - auto attr = op.getDataAttr(); - if (attr && (*attr == cuf::DataAttribute::Device || - *attr == cuf::DataAttribute::Managed || - *attr == cuf::DataAttribute::Constant)) - return true; - return false; -} - static mlir::Value createConvertOp(mlir::PatternRewriter &rewriter, mlir::Location loc, mlir::Type toTy, mlir::Value val) { @@ -388,7 +379,7 @@ struct DeclareOpConversion : public mlir::OpRewritePattern { if (auto addrOfOp = op.getMemref().getDefiningOp()) { if (auto global = symTab.lookup( addrOfOp.getSymbol().getRootReference().getValue())) { - if (isDeviceGlobal(global)) { + if (cuf::isRegisteredDeviceGlobal(global)) { rewriter.setInsertionPointAfter(addrOfOp); auto mod = op->getParentOfType(); fir::FirOpBuilder builder(rewriter, mod); @@ -833,7 +824,7 @@ class CUFOpConversion : public fir::impl::CUFOpConversionBase { addrOfOp.getSymbol().getRootReference().getValue())) { if (mlir::isa(fir::unwrapRefType(global.getType()))) return true; - if (isDeviceGlobal(global)) + if (cuf::isRegisteredDeviceGlobal(global)) return false; } } diff --git a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp index 3b79d6d311b71..b09bbf6106dbb 100644 --- a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp +++ b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp @@ -332,8 +332,6 @@ class CfgConversion : public fir::impl::CFGConversionBase { public: using CFGConversionBase::CFGConversionBase; - CfgConversion(bool setNSW) { this->setNSW = setNSW; } - void runOnOperation() override { auto *context = &this->getContext(); mlir::RewritePatternSet patterns(context); @@ -365,7 +363,3 @@ void fir::populateCfgConversionRewrites(mlir::RewritePatternSet &patterns, patterns.insert( patterns.getContext(), forceLoopToExecuteOnce, setNSW); } - -std::unique_ptr fir::createCFGConversionPassWithNSW() { - return std::make_unique(true); -} diff --git a/flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp b/flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp index cfd90ff723793..4f6974ee52695 100644 --- a/flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp +++ b/flang/lib/Optimizer/Transforms/ExternalNameConversion.cpp @@ -60,23 +60,30 @@ void ExternalNameConversionPass::runOnOperation() { llvm::DenseMap remappings; + auto processFctOrGlobal = [&](mlir::Operation &funcOrGlobal) { + auto symName = funcOrGlobal.getAttrOfType( + mlir::SymbolTable::getSymbolAttrName()); + auto deconstructedName = fir::NameUniquer::deconstruct(symName); + if (fir::NameUniquer::isExternalFacingUniquedName(deconstructedName)) { + auto newName = mangleExternalName(deconstructedName, appendUnderscoreOpt); + auto newAttr = mlir::StringAttr::get(context, newName); + mlir::SymbolTable::setSymbolName(&funcOrGlobal, newAttr); + auto newSymRef = mlir::FlatSymbolRefAttr::get(newAttr); + remappings.try_emplace(symName, newSymRef); + if (llvm::isa(funcOrGlobal)) + funcOrGlobal.setAttr(fir::getInternalFuncNameAttrName(), symName); + } + }; + auto renameFuncOrGlobalInModule = [&](mlir::Operation *module) { - for (auto &funcOrGlobal : module->getRegion(0).front()) { - if (llvm::isa(funcOrGlobal) || - llvm::isa(funcOrGlobal)) { - auto symName = funcOrGlobal.getAttrOfType( - mlir::SymbolTable::getSymbolAttrName()); - auto deconstructedName = fir::NameUniquer::deconstruct(symName); - if (fir::NameUniquer::isExternalFacingUniquedName(deconstructedName)) { - auto newName = - mangleExternalName(deconstructedName, appendUnderscoreOpt); - auto newAttr = mlir::StringAttr::get(context, newName); - mlir::SymbolTable::setSymbolName(&funcOrGlobal, newAttr); - auto newSymRef = mlir::FlatSymbolRefAttr::get(newAttr); - remappings.try_emplace(symName, newSymRef); - if (llvm::isa(funcOrGlobal)) - funcOrGlobal.setAttr(fir::getInternalFuncNameAttrName(), symName); - } + for (auto &op : module->getRegion(0).front()) { + if (mlir::isa(op)) { + processFctOrGlobal(op); + } else if (auto gpuMod = mlir::dyn_cast(op)) { + for (auto &gpuOp : gpuMod.getBodyRegion().front()) + if (mlir::isa(gpuOp)) + processFctOrGlobal(gpuOp); } } }; @@ -85,11 +92,6 @@ void ExternalNameConversionPass::runOnOperation() { // globals. renameFuncOrGlobalInModule(op); - // Do the same in GPU modules. - if (auto mod = mlir::dyn_cast_or_null(*op)) - for (auto gpuMod : mod.getOps()) - renameFuncOrGlobalInModule(gpuMod); - if (remappings.empty()) return; @@ -97,11 +99,18 @@ void ExternalNameConversionPass::runOnOperation() { op.walk([&remappings](mlir::Operation *nestedOp) { llvm::SmallVector> updates; for (const mlir::NamedAttribute &attr : nestedOp->getAttrDictionary()) - if (auto symRef = llvm::dyn_cast(attr.getValue())) - if (auto remap = remappings.find(symRef.getRootReference()); - remap != remappings.end()) + if (auto symRef = llvm::dyn_cast(attr.getValue())) { + if (auto remap = remappings.find(symRef.getLeafReference()); + remap != remappings.end()) { + mlir::SymbolRefAttr symAttr = mlir::FlatSymbolRefAttr(remap->second); + if (mlir::isa(nestedOp)) + symAttr = mlir::SymbolRefAttr::get( + symRef.getRootReference(), + {mlir::FlatSymbolRefAttr(remap->second)}); updates.emplace_back(std::pair{ - attr.getName(), mlir::SymbolRefAttr(remap->second)}); + attr.getName(), symAttr}); + } + } for (auto update : updates) nestedOp->setAttr(update.first, update.second); }); diff --git a/flang/lib/Parser/openmp-parsers.cpp b/flang/lib/Parser/openmp-parsers.cpp index 86d475c1a1542..67385c03f66c8 100644 --- a/flang/lib/Parser/openmp-parsers.cpp +++ b/flang/lib/Parser/openmp-parsers.cpp @@ -99,6 +99,25 @@ constexpr ModifierList modifierList(Separator sep) { return ModifierList(sep); } +// Parse the input as any modifier from ClauseTy, but only succeed if +// the result was the SpecificTy. It requires that SpecificTy is one +// of the alternatives in ClauseTy::Modifier. +// The reason to have this is that ClauseTy::Modifier has "source", +// while specific modifiers don't. This class allows to parse a specific +// modifier together with obtaining its location. +template +struct SpecificModifierParser { + using resultType = typename ClauseTy::Modifier; + std::optional Parse(ParseState &state) const { + if (auto result{attempt(Parser{}).Parse(state)}) { + if (std::holds_alternative(result->u)) { + return result; + } + } + return std::nullopt; + } +}; + // OpenMP Clauses // [5.0] 2.1.6 iterator-specifier -> type-declaration-stmt = subscript-triple | @@ -232,6 +251,11 @@ TYPE_PARSER(construct( "TASK" >> pure(OmpReductionModifier::Value::Task) || "DEFAULT" >> pure(OmpReductionModifier::Value::Default))) +TYPE_PARSER(construct( // + "STEP" >> parenthesized(scalarIntExpr))) + +TYPE_PARSER(construct(scalarIntExpr)) + TYPE_PARSER(construct( "DEPOBJ" >> pure(OmpTaskDependenceType::Value::Depobj) || "IN"_id >> pure(OmpTaskDependenceType::Value::In) || @@ -282,9 +306,17 @@ TYPE_PARSER(sourced( TYPE_PARSER(sourced(construct(OmpDirectiveNameParser{}))) +TYPE_PARSER(sourced(construct( + Parser{}))) + TYPE_PARSER(sourced(construct( Parser{}))) +TYPE_PARSER(sourced( + construct(Parser{}) || + construct(Parser{}) || + construct(Parser{}))) + TYPE_PARSER(sourced(construct( sourced(construct(Parser{}) || construct(Parser{}) || @@ -306,6 +338,9 @@ TYPE_PARSER(sourced(construct(sourced( construct(Parser{}) || construct(Parser{}))))) +TYPE_PARSER(sourced(construct( + Parser{}))) + TYPE_PARSER(sourced(construct( sourced(construct(Parser{}) || construct(Parser{}) || @@ -407,7 +442,12 @@ TYPE_PARSER(construct( // OMP 5.0 2.19.5.6 IN_REDUCTION (reduction-identifier: variable-name-list) TYPE_PARSER(construct( - Parser{} / ":", Parser{})) + maybe(nonemptyList(Parser{}) / ":"), + Parser{})) + +TYPE_PARSER(construct( + maybe(nonemptyList(Parser{}) / ":"), + Parser{})) // OMP 5.0 2.11.4 allocate-clause -> ALLOCATE ([allocator:] variable-name-list) // OMP 5.2 2.13.4 allocate-clause -> ALLOCATE ([allocate-modifier @@ -460,13 +500,33 @@ TYPE_PARSER(construct( applyFunction(makeMobClause, modifierList(maybe(","_tok)), Parser{}))) -TYPE_CONTEXT_PARSER("Omp LINEAR clause"_en_US, - construct( - construct(construct( - Parser{}, parenthesized(nonemptyList(name)), - maybe(":" >> scalarIntConstantExpr))) || - construct(construct( - nonemptyList(name), maybe(":" >> scalarIntConstantExpr))))) +OmpLinearClause makeLinearFromOldSyntax(OmpLinearClause::Modifier &&lm, + OmpObjectList &&objs, std::optional &&ssm) { + std::list mods; + mods.emplace_back(std::move(lm)); + if (ssm) { + mods.emplace_back(std::move(*ssm)); + } + return OmpLinearClause{std::move(objs), + mods.empty() ? decltype(mods){} : std::move(mods), + /*PostModified=*/false}; +} + +TYPE_PARSER( + // Parse the "modifier(x)" first, because syntacticaly it will match + // an array element (i.e. a list item). + // LINEAR(linear-modifier(list) [: step-simple-modifier]) + construct( // + applyFunction(makeLinearFromOldSyntax, + SpecificModifierParser{}, + parenthesized(Parser{}), + maybe(":"_tok >> SpecificModifierParser{}))) || + // LINEAR(list [: modifiers]) + construct( // + Parser{}, + maybe(":"_tok >> nonemptyList(Parser{})), + /*PostModified=*/pure(true))) // OpenMPv5.2 12.5.2 detach-clause -> DETACH (event-handle) TYPE_PARSER(construct(Parser{})) @@ -507,6 +567,16 @@ TYPE_PARSER(construct( "TEAMS" >> pure(OmpBindClause::Binding::Teams) || "THREAD" >> pure(OmpBindClause::Binding::Thread))) +TYPE_PARSER(construct( + "EXECUTION" >> pure(OmpAtClause::ActionTime::Execution) || + "COMPILATION" >> pure(OmpAtClause::ActionTime::Compilation))) + +TYPE_PARSER(construct( + "FATAL" >> pure(OmpSeverityClause::Severity::Fatal) || + "WARNING" >> pure(OmpSeverityClause::Severity::Warning))) + +TYPE_PARSER(construct(expr)) + TYPE_PARSER( "ACQUIRE" >> construct(construct()) || "ACQ_REL" >> construct(construct()) || @@ -518,6 +588,8 @@ TYPE_PARSER( parenthesized(Parser{}))) || "ALLOCATOR" >> construct(construct( parenthesized(scalarIntExpr))) || + "AT" >> construct(construct( + parenthesized(Parser{}))) || "ATOMIC_DEFAULT_MEM_ORDER" >> construct(construct( parenthesized(Parser{}))) || @@ -585,6 +657,8 @@ TYPE_PARSER( "MAP" >> construct(construct( parenthesized(Parser{}))) || "MERGEABLE" >> construct(construct()) || + "MESSAGE" >> construct(construct( + parenthesized(Parser{}))) || "NOGROUP" >> construct(construct()) || "NONTEMPORAL" >> construct(construct( parenthesized(nonemptyList(name)))) || @@ -597,6 +671,7 @@ TYPE_PARSER( parenthesized(scalarIntExpr))) || "NUM_THREADS" >> construct(construct( parenthesized(scalarIntExpr))) || + "OMPX_BARE" >> construct(construct()) || "ORDER" >> construct(construct( parenthesized(Parser{}))) || "ORDERED" >> construct(construct( @@ -609,15 +684,15 @@ TYPE_PARSER( parenthesized(Parser{}))) || "PROC_BIND" >> construct(construct( parenthesized(Parser{}))) || - "REDUCTION" >> construct(construct( - parenthesized(Parser{}))) || + "REDUCTION"_id >> construct(construct( + parenthesized(Parser{}))) || "IN_REDUCTION" >> construct(construct( parenthesized(Parser{}))) || "DETACH" >> construct(construct( parenthesized(Parser{}))) || "TASK_REDUCTION" >> construct(construct( - parenthesized(Parser{}))) || + parenthesized(Parser{}))) || "RELAXED" >> construct(construct()) || "RELEASE" >> construct(construct()) || "REVERSE_OFFLOAD" >> @@ -627,6 +702,8 @@ TYPE_PARSER( "SCHEDULE" >> construct(construct( parenthesized(Parser{}))) || "SEQ_CST" >> construct(construct()) || + "SEVERITY" >> construct(construct( + parenthesized(Parser{}))) || "SHARED" >> construct(construct( parenthesized(Parser{}))) || "SIMD"_id >> construct(construct()) || @@ -739,6 +816,9 @@ TYPE_PARSER(sourced(construct( TYPE_PARSER(sourced(construct(verbatim("CANCEL"_tok), Parser{}, maybe("IF" >> parenthesized(scalarLogicalExpr))))) +TYPE_PARSER(sourced(construct( + parenthesized(indirect(Parser{}))))) + // 2.17.7 Atomic construct/2.17.8 Flush construct [OpenMP 5.0] // memory-order-clause -> // seq_cst @@ -767,6 +847,7 @@ TYPE_PARSER(construct( // atomic-clause -> memory-order-clause | HINT(hint-expression) TYPE_PARSER(sourced(construct( construct(Parser{}) || + construct("FAIL" >> Parser{}) || construct("HINT" >> sourced(construct( construct(parenthesized(constantExpr)))))))) @@ -946,6 +1027,9 @@ TYPE_PARSER(sourced(construct(verbatim("CRITICAL"_tok), TYPE_PARSER(construct( Parser{}, block, Parser{})) +TYPE_PARSER(sourced(construct( + verbatim("ERROR"_tok), Parser{}))) + // 2.11.3 Executable Allocate directive TYPE_PARSER( sourced(construct(verbatim("ALLOCATE"_tok), @@ -1043,6 +1127,7 @@ TYPE_CONTEXT_PARSER("OpenMP construct"_en_US, // OpenMPStandaloneConstruct to resolve !$OMP ORDERED construct(Parser{}), construct(Parser{}), + construct(Parser{}), construct(Parser{}), construct(Parser{}), construct(Parser{}), diff --git a/flang/lib/Parser/parsing.cpp b/flang/lib/Parser/parsing.cpp index e2381a6b8ffa3..8fcac7b3cacb1 100644 --- a/flang/lib/Parser/parsing.cpp +++ b/flang/lib/Parser/parsing.cpp @@ -159,8 +159,9 @@ void Parsing::EmitPreprocessedSource( // which signifies a comment (directive) in both source forms. inDirective = true; } - if (inDirective && directive.size() < directiveNameLength && - IsLetter(ch)) { + bool inDirectiveSentinel{ + inDirective && directive.size() < directiveNameLength}; + if (inDirectiveSentinel && IsLetter(ch)) { directive += getOriginalChar(ch); } @@ -211,7 +212,8 @@ void Parsing::EmitPreprocessedSource( out << ' '; } } - if (!inContinuation && position && position->column <= 72 && ch != ' ') { + if (!inContinuation && !inDirectiveSentinel && position && + position->column <= 72 && ch != ' ') { // Preserve original indentation for (; column < position->column; ++column) { out << ' '; diff --git a/flang/lib/Parser/unparse.cpp b/flang/lib/Parser/unparse.cpp index 4782cc1f2d7d7..0a6af7435b4a2 100644 --- a/flang/lib/Parser/unparse.cpp +++ b/flang/lib/Parser/unparse.cpp @@ -2133,23 +2133,78 @@ class UnparseVisitor { Walk(std::get>>(x.t), ": "); Walk(std::get(x.t)); } - void Unparse(const OmpLinearClause::WithoutModifier &x) { - Walk(x.names, ", "); - Walk(":", x.step); + void Unparse(const OmpStepSimpleModifier &x) { Walk(x.v); } + void Unparse(const OmpStepComplexModifier &x) { + Word("STEP("); + Walk(x.v); + Put(")"); } - void Unparse(const OmpLinearClause::WithModifier &x) { - Walk(x.modifier), Put("("), Walk(x.names, ","), Put(")"); - Walk(":", x.step); + void Unparse(const OmpLinearClause &x) { + using Modifier = OmpLinearClause::Modifier; + auto &modifiers{std::get>>(x.t)}; + if (std::get(x.t)) { // PostModified + Walk(std::get(x.t)); + Walk(": ", modifiers); + } else { + // Unparse using pre-5.2 syntax. + bool HasStepModifier{false}, HasLinearModifier{false}; + + if (modifiers) { + bool NeedComma{false}; + for (const Modifier &m : *modifiers) { + // Print all linear modifiers in case we need to unparse an + // incorrect tree. + if (auto *lmod{std::get_if(&m.u)}) { + if (NeedComma) { + Put(","); + } + Walk(*lmod); + HasLinearModifier = true; + NeedComma = true; + } else { + // If not linear-modifier, then it has to be step modifier. + HasStepModifier = true; + } + } + } + + if (HasLinearModifier) { + Put("("); + } + Walk(std::get(x.t)); + if (HasLinearModifier) { + Put(")"); + } + + if (HasStepModifier) { + Put(": "); + bool NeedComma{false}; + for (const Modifier &m : *modifiers) { + if (!std::holds_alternative(m.u)) { + if (NeedComma) { + Put(","); + } + common::visit([&](auto &&s) { Walk(s); }, m.u); + NeedComma = true; + } + } + } + } } void Unparse(const OmpReductionClause &x) { using Modifier = OmpReductionClause::Modifier; - Walk(std::get>>(x.t), ":"); + Walk(std::get>>(x.t), ": "); Walk(std::get(x.t)); } void Unparse(const OmpDetachClause &x) { Walk(x.v); } void Unparse(const OmpInReductionClause &x) { - Walk(std::get(x.t)); - Put(":"); + using Modifier = OmpInReductionClause::Modifier; + Walk(std::get>>(x.t), ": "); + Walk(std::get(x.t)); + } + void Unparse(const OmpTaskReductionClause &x) { + using Modifier = OmpTaskReductionClause::Modifier; + Walk(std::get>>(x.t), ": "); Walk(std::get(x.t)); } void Unparse(const OmpAllocateClause &x) { @@ -2651,6 +2706,15 @@ class UnparseVisitor { Put(")\n"); EndOpenMP(); } + bool Pre(const OmpMessageClause &x) { + Walk(x.v); + return false; + } + void Unparse(const OpenMPErrorConstruct &x) { + Word("!$OMP ERROR "); + Walk(x.t); + Put("\n"); + } void Unparse(const OmpSectionsDirective &x) { switch (x.v) { case llvm::omp::Directive::OMPD_sections: @@ -2702,10 +2766,16 @@ class UnparseVisitor { Put("\n"); EndOpenMP(); } + void Unparse(const OmpFailClause &x) { + Word("FAIL("); + Walk(x.v); + Put(")"); + } void Unparse(const OmpMemoryOrderClause &x) { Walk(x.v); } void Unparse(const OmpAtomicClause &x) { common::visit(common::visitors{ [&](const OmpMemoryOrderClause &y) { Walk(y); }, + [&](const OmpFailClause &y) { Walk(y); }, [&](const OmpClause &z) { Walk(z); }, }, x.u); @@ -2835,6 +2905,7 @@ class UnparseVisitor { WALK_NESTED_ENUM(InquireSpec::LogVar, Kind) WALK_NESTED_ENUM(ProcedureStmt, Kind) // R1506 WALK_NESTED_ENUM(UseStmt, ModuleNature) // R1410 + WALK_NESTED_ENUM(OmpAtClause, ActionTime) // OMP at WALK_NESTED_ENUM(OmpBindClause, Binding) // OMP bind WALK_NESTED_ENUM(OmpProcBindClause, AffinityPolicy) // OMP proc_bind WALK_NESTED_ENUM(OmpDefaultClause, DataSharingAttribute) // OMP default @@ -2846,6 +2917,7 @@ class UnparseVisitor { WALK_NESTED_ENUM(OmpOrderingModifier, Value) // OMP ordering-modifier WALK_NESTED_ENUM(OmpTaskDependenceType, Value) // OMP task-dependence-type WALK_NESTED_ENUM(OmpScheduleClause, Kind) // OMP schedule-kind + WALK_NESTED_ENUM(OmpSeverityClause, Severity) // OMP severity WALK_NESTED_ENUM(OmpDeviceModifier, Value) // OMP device modifier WALK_NESTED_ENUM( OmpDeviceTypeClause, DeviceTypeDescription) // OMP device_type diff --git a/flang/lib/Semantics/check-cuda.cpp b/flang/lib/Semantics/check-cuda.cpp index 79b7a26ef222f..9c044a47c7983 100644 --- a/flang/lib/Semantics/check-cuda.cpp +++ b/flang/lib/Semantics/check-cuda.cpp @@ -340,7 +340,7 @@ template class DeviceContextChecker { void ErrorIfHostSymbol(const A &expr, parser::CharBlock source) { if (const Symbol * hostArray{FindHostArray{}(expr)}) { context_.Say(source, - "Host array '%s' cannot be present in CUF kernel"_err_en_US, + "Host array '%s' cannot be present in device context"_err_en_US, hostArray->name()); } } @@ -387,13 +387,10 @@ template class DeviceContextChecker { Check(x.value()); }, [&](const common::Indirection &x) { - if (IsCUFKernelDo) { - const evaluate::Assignment *assign{ - semantics::GetAssignment(x.value())}; - if (assign) { - ErrorIfHostSymbol(assign->lhs, source); - ErrorIfHostSymbol(assign->rhs, source); - } + if (const evaluate::Assignment * + assign{semantics::GetAssignment(x.value())}) { + ErrorIfHostSymbol(assign->lhs, source); + ErrorIfHostSymbol(assign->rhs, source); } if (auto msg{ActionStmtChecker::WhyNotOk(x)}) { context_.Say(source, std::move(*msg)); diff --git a/flang/lib/Semantics/check-omp-structure.cpp b/flang/lib/Semantics/check-omp-structure.cpp index f09542e5b5df1..95b962f5daf57 100644 --- a/flang/lib/Semantics/check-omp-structure.cpp +++ b/flang/lib/Semantics/check-omp-structure.cpp @@ -51,6 +51,30 @@ std::string TryVersion(unsigned version) { return "try -fopenmp-version=" + std::to_string(version); } +static const parser::Designator *GetDesignatorFromObj( + const parser::OmpObject &object) { + return std::get_if(&object.u); +} + +static const parser::DataRef *GetDataRefFromObj( + const parser::OmpObject &object) { + if (auto *desg{GetDesignatorFromObj(object)}) { + return std::get_if(&desg->u); + } + return nullptr; +} + +static const parser::ArrayElement *GetArrayElementFromObj( + const parser::OmpObject &object) { + if (auto *dataRef{GetDataRefFromObj(object)}) { + using ElementIndirection = common::Indirection; + if (auto *ind{std::get_if(&dataRef->u)}) { + return &ind->value(); + } + } + return nullptr; +} + // 'OmpWorkshareBlockChecker' is used to check the validity of the assignment // statements and the expressions enclosed in an OpenMP Workshare construct class OmpWorkshareBlockChecker { @@ -222,6 +246,10 @@ bool OmpStructureChecker::CheckAllowedClause(llvmOmpClause clause) { return CheckAllowed(clause); } +bool OmpStructureChecker::IsCommonBlock(const Symbol &sym) { + return sym.detailsIf() != nullptr; +} + bool OmpStructureChecker::IsVariableListItem(const Symbol &sym) { return evaluate::IsVariable(sym) || sym.attrs().test(Attr::POINTER); } @@ -383,6 +411,19 @@ void OmpStructureChecker::CheckMultListItems() { CheckMultipleOccurrence( listVars, nontempNameList, clause->source, "NONTEMPORAL"); } + + // Linear clause + for (auto [_, clause] : FindClauses(llvm::omp::Clause::OMPC_linear)) { + auto &linearClause{std::get(clause->u)}; + std::list nameList; + SymbolSourceMap symbols; + GetSymbolsInObjectList( + std::get(linearClause.v.t), symbols); + llvm::transform(symbols, std::back_inserter(nameList), [&](auto &&pair) { + return parser::Name{pair.second, const_cast(pair.first)}; + }); + CheckMultipleOccurrence(listVars, nameList, clause->source, "LINEAR"); + } } bool OmpStructureChecker::HasInvalidWorksharingNesting( @@ -513,18 +554,16 @@ void OmpStructureChecker::CheckHintClause( D *leftOmpClauseList, D *rightOmpClauseList) { auto checkForValidHintClause = [&](const D *clauseList) { for (const auto &clause : clauseList->v) { - const Fortran::parser::OmpClause *ompClause = nullptr; - if constexpr (std::is_same_v) { - ompClause = std::get_if(&clause.u); + const parser::OmpClause *ompClause = nullptr; + if constexpr (std::is_same_v) { + ompClause = std::get_if(&clause.u); if (!ompClause) continue; - } else if constexpr (std::is_same_v) { + } else if constexpr (std::is_same_v) { ompClause = &clause; } - if (const Fortran::parser::OmpClause::Hint *hintClause{ - std::get_if(&ompClause->u)}) { + if (const parser::OmpClause::Hint *hintClause{ + std::get_if(&ompClause->u)}) { std::optional hintValue = GetIntValue(hintClause->v); if (hintValue && *hintValue >= 0) { /*`omp_sync_hint_nonspeculative` and `omp_lock_hint_speculative`*/ @@ -752,7 +791,7 @@ void OmpStructureChecker::CheckSIMDNest(const parser::OpenMPConstruct &c) { // TODO: Check for declare simd regions. bool eligibleSIMD{false}; common::visit( - Fortran::common::visitors{ + common::visitors{ // Allow `!$OMP ORDERED SIMD` [&](const parser::OpenMPBlockConstruct &c) { const auto &beginBlockDir{ @@ -917,28 +956,13 @@ void OmpStructureChecker::CheckDistLinear( const auto &beginLoopDir{std::get(x.t)}; const auto &clauses{std::get(beginLoopDir.t)}; - semantics::UnorderedSymbolSet indexVars; + SymbolSourceMap indexVars; // Collect symbols of all the variables from linear clauses - for (const auto &clause : clauses.v) { - if (const auto *linearClause{ - std::get_if(&clause.u)}) { - - std::list values; - // Get the variant type - if (std::holds_alternative( - linearClause->v.u)) { - const auto &withM{ - std::get(linearClause->v.u)}; - values = withM.names; - } else { - const auto &withOutM{std::get( - linearClause->v.u)}; - values = withOutM.names; - } - for (auto const &v : values) { - indexVars.insert(*(v.symbol)); - } + for (auto &clause : clauses.v) { + if (auto *linearClause{std::get_if(&clause.u)}) { + auto &objects{std::get(linearClause->v.t)}; + GetSymbolsInObjectList(objects, indexVars); } } @@ -958,8 +982,8 @@ void OmpStructureChecker::CheckDistLinear( if (loop->IsDoNormal()) { const parser::Name &itrVal{GetLoopIndex(loop)}; if (itrVal.symbol) { - // Remove the symbol from the collcted set - indexVars.erase(*(itrVal.symbol)); + // Remove the symbol from the collected set + indexVars.erase(&itrVal.symbol->GetUltimate()); } collapseVal--; if (collapseVal == 0) { @@ -975,12 +999,10 @@ void OmpStructureChecker::CheckDistLinear( } // Show error for the remaining variables - for (auto var : indexVars) { - const Symbol &root{GetAssociationRoot(var)}; - context_.Say(parser::FindSourceLocation(x), - "Variable '%s' not allowed in `LINEAR` clause, only loop iterator " - "can be specified in `LINEAR` clause of a construct combined with " - "`DISTRIBUTE`"_err_en_US, + for (auto &[symbol, source] : indexVars) { + const Symbol &root{GetAssociationRoot(*symbol)}; + context_.Say(source, + "Variable '%s' not allowed in LINEAR clause, only loop iterator can be specified in LINEAR clause of a construct combined with DISTRIBUTE"_err_en_US, root.name()); } } @@ -1666,6 +1688,15 @@ void OmpStructureChecker::Leave(const parser::OpenMPDeclareTargetConstruct &x) { dirContext_.pop_back(); } +void OmpStructureChecker::Enter(const parser::OpenMPErrorConstruct &x) { + const auto &dir{std::get(x.t)}; + PushContextAndClauseSets(dir.source, llvm::omp::Directive::OMPD_error); +} + +void OmpStructureChecker::Leave(const parser::OpenMPErrorConstruct &x) { + dirContext_.pop_back(); +} + void OmpStructureChecker::Enter(const parser::OpenMPExecutableAllocate &x) { isPredefinedAllocator = true; const auto &dir{std::get(x.t)}; @@ -2088,7 +2119,7 @@ void OmpStructureChecker::CheckCancellationNest( eligibleCancellation = true; } break; - case Fortran::parser::OmpCancelType::Type::Do: + case parser::OmpCancelType::Type::Do: if (llvm::omp::nestedCancelDoAllowedSet.test( GetContextParent().directive)) { eligibleCancellation = true; @@ -2129,7 +2160,7 @@ void OmpStructureChecker::CheckCancellationNest( parser::ToUpperCaseLetters( parser::OmpCancelType::EnumToString(type))); break; - case Fortran::parser::OmpCancelType::Type::Do: + case parser::OmpCancelType::Type::Do: context_.Say(source, "%s %s directive is not closely nested inside " "the construct that matches the DO clause type"_err_en_US, @@ -2195,9 +2226,9 @@ inline void OmpStructureChecker::ErrIfAllocatableVariable( const auto &designator = std::get>(var.u); const auto *dataRef = - std::get_if(&designator.value().u); - const Fortran::parser::Name *name = - dataRef ? std::get_if(&dataRef->u) : nullptr; + std::get_if(&designator.value().u); + const parser::Name *name = + dataRef ? std::get_if(&dataRef->u) : nullptr; if (name) context_.Say(name->source, "%s must not have ALLOCATABLE " @@ -2217,10 +2248,8 @@ inline void OmpStructureChecker::ErrIfLHSAndRHSSymbolsMatch( const Symbol &varSymbol = vSyms.front(); for (const Symbol &symbol : evaluate::GetSymbolVector(*e)) { if (varSymbol == symbol) { - const Fortran::common::Indirection - *designator = std::get_if< - Fortran::common::Indirection>( - &expr.u); + const common::Indirection *designator = + std::get_if>(&expr.u); if (designator) { auto *z{var.typedExpr.get()}; auto *c{expr.typedExpr.get()}; @@ -2301,10 +2330,9 @@ void OmpStructureChecker::CheckAtomicCaptureStmt( common::visitors{ [&](const common::Indirection &designator) { const auto *dataRef = - std::get_if(&designator.value().u); - const auto *name = dataRef - ? std::get_if(&dataRef->u) - : nullptr; + std::get_if(&designator.value().u); + const auto *name = + dataRef ? std::get_if(&dataRef->u) : nullptr; if (name && IsAllocatable(*name->symbol)) context_.Say(name->source, "%s must not have ALLOCATABLE " @@ -2437,23 +2465,21 @@ void OmpStructureChecker::CheckAtomicCompareConstruct( // TODO: Allow cond-update-stmt once compare clause is supported. void OmpStructureChecker::CheckAtomicCaptureConstruct( const parser::OmpAtomicCapture &atomicCaptureConstruct) { - const Fortran::parser::AssignmentStmt &stmt1 = - std::get( - atomicCaptureConstruct.t) + const parser::AssignmentStmt &stmt1 = + std::get(atomicCaptureConstruct.t) .v.statement; - const auto &stmt1Var{std::get(stmt1.t)}; - const auto &stmt1Expr{std::get(stmt1.t)}; + const auto &stmt1Var{std::get(stmt1.t)}; + const auto &stmt1Expr{std::get(stmt1.t)}; - const Fortran::parser::AssignmentStmt &stmt2 = - std::get( - atomicCaptureConstruct.t) + const parser::AssignmentStmt &stmt2 = + std::get(atomicCaptureConstruct.t) .v.statement; - const auto &stmt2Var{std::get(stmt2.t)}; - const auto &stmt2Expr{std::get(stmt2.t)}; + const auto &stmt2Var{std::get(stmt2.t)}; + const auto &stmt2Expr{std::get(stmt2.t)}; - if (Fortran::semantics::checkForSingleVariableOnRHS(stmt1)) { + if (semantics::checkForSingleVariableOnRHS(stmt1)) { CheckAtomicCaptureStmt(stmt1); - if (Fortran::semantics::checkForSymbolMatch(stmt2)) { + if (semantics::checkForSymbolMatch(stmt2)) { // ATOMIC CAPTURE construct is of the form [capture-stmt, update-stmt] CheckAtomicUpdateStmt(stmt2); } else { @@ -2467,8 +2493,8 @@ void OmpStructureChecker::CheckAtomicCaptureConstruct( "Captured variable/array element/derived-type component %s expected to be assigned in the second statement of ATOMIC CAPTURE construct"_err_en_US, stmt1Expr.source); } - } else if (Fortran::semantics::checkForSymbolMatch(stmt1) && - Fortran::semantics::checkForSingleVariableOnRHS(stmt2)) { + } else if (semantics::checkForSymbolMatch(stmt1) && + semantics::checkForSingleVariableOnRHS(stmt2)) { // ATOMIC CAPTURE construct is of the form [update-stmt, capture-stmt] CheckAtomicUpdateStmt(stmt1); CheckAtomicCaptureStmt(stmt2); @@ -2489,21 +2515,30 @@ void OmpStructureChecker::CheckAtomicCaptureConstruct( void OmpStructureChecker::CheckAtomicMemoryOrderClause( const parser::OmpAtomicClauseList *leftHandClauseList, const parser::OmpAtomicClauseList *rightHandClauseList) { - int numMemoryOrderClause = 0; - auto checkForValidMemoryOrderClause = - [&](const parser::OmpAtomicClauseList *clauseList) { - for (const auto &clause : clauseList->v) { - if (std::get_if(&clause.u)) { - numMemoryOrderClause++; - if (numMemoryOrderClause > 1) { - context_.Say(clause.source, - "More than one memory order clause not allowed on " - "OpenMP Atomic construct"_err_en_US); - return; - } + int numMemoryOrderClause{0}; + int numFailClause{0}; + auto checkForValidMemoryOrderClause = [&](const parser::OmpAtomicClauseList + *clauseList) { + for (const auto &clause : clauseList->v) { + if (std::get_if(&clause.u)) { + numFailClause++; + if (numFailClause > 1) { + context_.Say(clause.source, + "More than one FAIL clause not allowed on OpenMP ATOMIC construct"_err_en_US); + return; + } + } else { + if (std::get_if(&clause.u)) { + numMemoryOrderClause++; + if (numMemoryOrderClause > 1) { + context_.Say(clause.source, + "More than one memory order clause not allowed on OpenMP ATOMIC construct"_err_en_US); + return; } } - }; + } + } + }; if (leftHandClauseList) { checkForValidMemoryOrderClause(leftHandClauseList); } @@ -2686,12 +2721,12 @@ void OmpStructureChecker::Leave(const parser::OmpClauseList &) { } } } - - // Sema checks related to presence of multiple list items within the same - // clause - CheckMultListItems(); } // SIMD + // Semantic checks related to presence of multiple list items within the same + // clause + CheckMultListItems(); + // 2.7.3 Single Construct Restriction if (GetContext().directive == llvm::omp::Directive::OMPD_end_single) { CheckNotAllowedIfClause( @@ -2775,8 +2810,6 @@ void OmpStructureChecker::Enter(const parser::OmpClause &x) { // Following clauses do not have a separate node in parse-tree.h. CHECK_SIMPLE_CLAUSE(Absent, OMPC_absent) -CHECK_SIMPLE_CLAUSE(AcqRel, OMPC_acq_rel) -CHECK_SIMPLE_CLAUSE(Acquire, OMPC_acquire) CHECK_SIMPLE_CLAUSE(Affinity, OMPC_affinity) CHECK_SIMPLE_CLAUSE(Capture, OMPC_capture) CHECK_SIMPLE_CLAUSE(Contains, OMPC_contains) @@ -2793,7 +2826,6 @@ CHECK_SIMPLE_CLAUSE(Grainsize, OMPC_grainsize) CHECK_SIMPLE_CLAUSE(Hint, OMPC_hint) CHECK_SIMPLE_CLAUSE(Holds, OMPC_holds) CHECK_SIMPLE_CLAUSE(Inclusive, OMPC_inclusive) -CHECK_SIMPLE_CLAUSE(InReduction, OMPC_in_reduction) CHECK_SIMPLE_CLAUSE(Match, OMPC_match) CHECK_SIMPLE_CLAUSE(Nontemporal, OMPC_nontemporal) CHECK_SIMPLE_CLAUSE(NumTasks, OMPC_num_tasks) @@ -2812,13 +2844,9 @@ CHECK_SIMPLE_CLAUSE(Nogroup, OMPC_nogroup) CHECK_SIMPLE_CLAUSE(Notinbranch, OMPC_notinbranch) CHECK_SIMPLE_CLAUSE(Partial, OMPC_partial) CHECK_SIMPLE_CLAUSE(ProcBind, OMPC_proc_bind) -CHECK_SIMPLE_CLAUSE(Release, OMPC_release) -CHECK_SIMPLE_CLAUSE(Relaxed, OMPC_relaxed) -CHECK_SIMPLE_CLAUSE(SeqCst, OMPC_seq_cst) CHECK_SIMPLE_CLAUSE(Simd, OMPC_simd) CHECK_SIMPLE_CLAUSE(Sizes, OMPC_sizes) CHECK_SIMPLE_CLAUSE(Permutation, OMPC_permutation) -CHECK_SIMPLE_CLAUSE(TaskReduction, OMPC_task_reduction) CHECK_SIMPLE_CLAUSE(Uniform, OMPC_uniform) CHECK_SIMPLE_CLAUSE(Unknown, OMPC_unknown) CHECK_SIMPLE_CLAUSE(Untied, OMPC_untied) @@ -2841,8 +2869,6 @@ CHECK_SIMPLE_CLAUSE(Align, OMPC_align) CHECK_SIMPLE_CLAUSE(Compare, OMPC_compare) CHECK_SIMPLE_CLAUSE(CancellationConstructType, OMPC_cancellation_construct_type) CHECK_SIMPLE_CLAUSE(OmpxAttribute, OMPC_ompx_attribute) -CHECK_SIMPLE_CLAUSE(OmpxBare, OMPC_ompx_bare) -CHECK_SIMPLE_CLAUSE(Fail, OMPC_fail) CHECK_SIMPLE_CLAUSE(Weak, OMPC_weak) CHECK_REQ_SCALAR_INT_CLAUSE(NumTeams, OMPC_num_teams) @@ -2855,6 +2881,53 @@ CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Collapse, OMPC_collapse) CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Safelen, OMPC_safelen) CHECK_REQ_CONSTANT_SCALAR_INT_CLAUSE(Simdlen, OMPC_simdlen) +void OmpStructureChecker::Enter(const parser::OmpClause::AcqRel &) { + if (!isFailClause) + CheckAllowedClause(llvm::omp::Clause::OMPC_acq_rel); +} + +void OmpStructureChecker::Enter(const parser::OmpClause::Acquire &) { + if (!isFailClause) + CheckAllowedClause(llvm::omp::Clause::OMPC_acquire); +} + +void OmpStructureChecker::Enter(const parser::OmpClause::Release &) { + if (!isFailClause) + CheckAllowedClause(llvm::omp::Clause::OMPC_release); +} + +void OmpStructureChecker::Enter(const parser::OmpClause::Relaxed &) { + if (!isFailClause) + CheckAllowedClause(llvm::omp::Clause::OMPC_relaxed); +} + +void OmpStructureChecker::Enter(const parser::OmpClause::SeqCst &) { + if (!isFailClause) + CheckAllowedClause(llvm::omp::Clause::OMPC_seq_cst); +} + +void OmpStructureChecker::Enter(const parser::OmpClause::Fail &) { + assert(!isFailClause && "Unexpected FAIL clause inside a FAIL clause?"); + isFailClause = true; + CheckAllowedClause(llvm::omp::Clause::OMPC_fail); +} + +void OmpStructureChecker::Leave(const parser::OmpClause::Fail &) { + assert(isFailClause && "Expected to be inside a FAIL clause here"); + isFailClause = false; +} + +void OmpStructureChecker::Enter(const parser::OmpFailClause &) { + assert(!isFailClause && "Unexpected FAIL clause inside a FAIL clause?"); + isFailClause = true; + CheckAllowedClause(llvm::omp::Clause::OMPC_fail); +} + +void OmpStructureChecker::Leave(const parser::OmpFailClause &) { + assert(isFailClause && "Expected to be inside a FAIL clause here"); + isFailClause = false; +} + // Restrictions specific to each clause are implemented apart from the // generalized restrictions. @@ -2883,195 +2956,262 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Destroy &x) { void OmpStructureChecker::Enter(const parser::OmpClause::Reduction &x) { CheckAllowedClause(llvm::omp::Clause::OMPC_reduction); + auto &objects{std::get(x.v.t)}; + if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_reduction, GetContext().clauseSource, context_)) { - if (CheckReductionOperators(x)) { - CheckReductionTypeList(x); - } auto &modifiers{OmpGetModifiers(x.v)}; + const auto *ident{ + OmpGetUniqueModifier(modifiers)}; + assert(ident && "reduction-identifier is a required modifier"); + if (CheckReductionOperator(*ident, OmpGetModifierSource(modifiers, ident), + llvm::omp::OMPC_reduction)) { + CheckReductionObjectTypes(objects, *ident); + } using ReductionModifier = parser::OmpReductionModifier; - if (auto *maybeModifier{ - OmpGetUniqueModifier(modifiers)}) { - CheckReductionModifier(*maybeModifier); + if (auto *modifier{OmpGetUniqueModifier(modifiers)}) { + CheckReductionModifier(*modifier); } } + CheckReductionObjects(objects, llvm::omp::Clause::OMPC_reduction); + + // If this is a worksharing construct then ensure the reduction variable + // is not private in the parallel region that it binds to. + if (llvm::omp::nestedReduceWorkshareAllowedSet.test(GetContext().directive)) { + CheckSharedBindingInOuterContext(objects); + } } -bool OmpStructureChecker::CheckReductionOperators( - const parser::OmpClause::Reduction &x) { - bool ok = false; - auto &modifiers{OmpGetModifiers(x.v)}; - if (const auto *ident{ - OmpGetUniqueModifier(modifiers)}) { - - auto visitOperator{[&](const parser::DefinedOperator &dOpr) { - if (const auto *intrinsicOp{ - std::get_if( - &dOpr.u)}) { - ok = CheckIntrinsicOperator(*intrinsicOp); - } else { - context_.Say(GetContext().clauseSource, - "Invalid reduction operator in REDUCTION clause."_err_en_US, - ContextDirectiveAsFortran()); - } - }}; +void OmpStructureChecker::Enter(const parser::OmpClause::InReduction &x) { + CheckAllowedClause(llvm::omp::Clause::OMPC_in_reduction); + auto &objects{std::get(x.v.t)}; - auto visitDesignator{[&](const parser::ProcedureDesignator &procD) { - const parser::Name *name{std::get_if(&procD.u)}; - if (name && name->symbol) { - const SourceName &realName{name->symbol->GetUltimate().name()}; - if (realName == "max" || realName == "min" || realName == "iand" || - realName == "ior" || realName == "ieor") { - ok = true; - } - } - if (!ok) { + if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_in_reduction, + GetContext().clauseSource, context_)) { + auto &modifiers{OmpGetModifiers(x.v)}; + const auto *ident{ + OmpGetUniqueModifier(modifiers)}; + assert(ident && "reduction-identifier is a required modifier"); + if (CheckReductionOperator(*ident, OmpGetModifierSource(modifiers, ident), + llvm::omp::OMPC_in_reduction)) { + CheckReductionObjectTypes(objects, *ident); + } + } + CheckReductionObjects(objects, llvm::omp::Clause::OMPC_in_reduction); +} + +void OmpStructureChecker::Enter(const parser::OmpClause::TaskReduction &x) { + CheckAllowedClause(llvm::omp::Clause::OMPC_task_reduction); + auto &objects{std::get(x.v.t)}; + + if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_task_reduction, + GetContext().clauseSource, context_)) { + auto &modifiers{OmpGetModifiers(x.v)}; + const auto *ident{ + OmpGetUniqueModifier(modifiers)}; + assert(ident && "reduction-identifier is a required modifier"); + if (CheckReductionOperator(*ident, OmpGetModifierSource(modifiers, ident), + llvm::omp::OMPC_task_reduction)) { + CheckReductionObjectTypes(objects, *ident); + } + } + CheckReductionObjects(objects, llvm::omp::Clause::OMPC_task_reduction); +} + +bool OmpStructureChecker::CheckReductionOperator( + const parser::OmpReductionIdentifier &ident, parser::CharBlock source, + llvm::omp::Clause clauseId) { + auto visitOperator{[&](const parser::DefinedOperator &dOpr) { + if (const auto *intrinsicOp{ + std::get_if(&dOpr.u)}) { + switch (*intrinsicOp) { + case parser::DefinedOperator::IntrinsicOperator::Add: + case parser::DefinedOperator::IntrinsicOperator::Multiply: + case parser::DefinedOperator::IntrinsicOperator::AND: + case parser::DefinedOperator::IntrinsicOperator::OR: + case parser::DefinedOperator::IntrinsicOperator::EQV: + case parser::DefinedOperator::IntrinsicOperator::NEQV: + return true; + case parser::DefinedOperator::IntrinsicOperator::Subtract: context_.Say(GetContext().clauseSource, - "Invalid reduction identifier in REDUCTION " - "clause."_err_en_US, + "The minus reduction operator is deprecated since OpenMP 5.2 and is not supported in the REDUCTION clause."_err_en_US, ContextDirectiveAsFortran()); + return false; + default: + break; } - }}; - common::visit(common::visitors{visitOperator, visitDesignator}, ident->u); - } + } + context_.Say(source, "Invalid reduction operator in %s clause."_err_en_US, + parser::ToUpperCaseLetters(getClauseName(clauseId).str())); + return false; + }}; - return ok; -} + auto visitDesignator{[&](const parser::ProcedureDesignator &procD) { + const parser::Name *name{std::get_if(&procD.u)}; + bool valid{false}; + if (name && name->symbol) { + const SourceName &realName{name->symbol->GetUltimate().name()}; + valid = + llvm::is_contained({"max", "min", "iand", "ior", "ieor"}, realName); + } + if (!valid) { + context_.Say(source, + "Invalid reduction identifier in %s clause."_err_en_US, + parser::ToUpperCaseLetters(getClauseName(clauseId).str())); + } + return valid; + }}; -bool OmpStructureChecker::CheckIntrinsicOperator( - const parser::DefinedOperator::IntrinsicOperator &op) { + return common::visit( + common::visitors{visitOperator, visitDesignator}, ident.u); +} - switch (op) { - case parser::DefinedOperator::IntrinsicOperator::Add: - case parser::DefinedOperator::IntrinsicOperator::Multiply: - case parser::DefinedOperator::IntrinsicOperator::AND: - case parser::DefinedOperator::IntrinsicOperator::OR: - case parser::DefinedOperator::IntrinsicOperator::EQV: - case parser::DefinedOperator::IntrinsicOperator::NEQV: - return true; - case parser::DefinedOperator::IntrinsicOperator::Subtract: - context_.Say(GetContext().clauseSource, - "The minus reduction operator is deprecated since OpenMP 5.2 and is " - "not supported in the REDUCTION clause."_err_en_US, - ContextDirectiveAsFortran()); - break; - default: - context_.Say(GetContext().clauseSource, - "Invalid reduction operator in REDUCTION clause."_err_en_US, - ContextDirectiveAsFortran()); +/// Check restrictions on objects that are common to all reduction clauses. +void OmpStructureChecker::CheckReductionObjects( + const parser::OmpObjectList &objects, llvm::omp::Clause clauseId) { + unsigned version{context_.langOptions().OpenMPVersion}; + SymbolSourceMap symbols; + GetSymbolsInObjectList(objects, symbols); + + // Array sections must be a contiguous storage, have non-zero length. + for (const parser::OmpObject &object : objects.v) { + CheckIfContiguous(object); + } + CheckReductionArraySection(objects, clauseId); + // An object must be definable. + CheckDefinableObjects(symbols, clauseId); + // Procedure pointers are not allowed. + CheckProcedurePointer(symbols, clauseId); + // Pointers must not have INTENT(IN). + CheckIntentInPointer(symbols, clauseId); + + // Disallow common blocks. + // Iterate on objects because `GetSymbolsInObjectList` expands common block + // names into the lists of their members. + for (const parser::OmpObject &object : objects.v) { + auto *symbol{GetObjectSymbol(object)}; + assert(symbol && "Expecting a symbol for object"); + if (IsCommonBlock(*symbol)) { + auto source{GetObjectSource(object)}; + context_.Say(source ? *source : GetContext().clauseSource, + "Common block names are not allowed in %s clause"_err_en_US, + parser::ToUpperCaseLetters(getClauseName(clauseId).str())); + } + } + + if (version >= 50) { + // Object cannot be a part of another object (except array elements) + CheckStructureComponent(objects, clauseId); + // If object is an array section or element, the base expression must be + // a language identifier. + for (const parser::OmpObject &object : objects.v) { + if (auto *elem{GetArrayElementFromObj(object)}) { + const parser::DataRef &base = elem->base; + if (!std::holds_alternative(base.u)) { + auto source{GetObjectSource(object)}; + context_.Say(source ? *source : GetContext().clauseSource, + "The base expression of an array element or section in %s clause must be an identifier"_err_en_US, + parser::ToUpperCaseLetters(getClauseName(clauseId).str())); + } + } + } + // Type parameter inquiries are not allowed. + for (const parser::OmpObject &object : objects.v) { + if (auto *dataRef{GetDataRefFromObj(object)}) { + if (IsDataRefTypeParamInquiry(dataRef)) { + auto source{GetObjectSource(object)}; + context_.Say(source ? *source : GetContext().clauseSource, + "Type parameter inquiry is not permitted in %s clause"_err_en_US, + parser::ToUpperCaseLetters(getClauseName(clauseId).str())); + } + } + } } - return false; } static bool IsReductionAllowedForType( - const parser::OmpClause::Reduction &x, const DeclTypeSpec &type) { - auto &modifiers{OmpGetModifiers(x.v)}; - const auto *definedOp{ - OmpGetUniqueModifier(modifiers)}; - if (!definedOp) { - return false; - } - // TODO: user defined reduction operators. Just allow everything for now. - bool ok{true}; - - auto IsLogical{[](const DeclTypeSpec &type) -> bool { + const parser::OmpReductionIdentifier &ident, const DeclTypeSpec &type) { + auto isLogical{[](const DeclTypeSpec &type) -> bool { return type.category() == DeclTypeSpec::Logical; }}; - auto IsCharacter{[](const DeclTypeSpec &type) -> bool { + auto isCharacter{[](const DeclTypeSpec &type) -> bool { return type.category() == DeclTypeSpec::Character; }}; - common::visit( - common::visitors{ - [&](const parser::DefinedOperator &dOpr) { - if (const auto *intrinsicOp{ - std::get_if( - &dOpr.u)}) { - // OMP5.2: The type [...] of a list item that appears in a - // reduction clause must be valid for the combiner expression - // See F2023: Table 10.2 - // .LT., .LE., .GT., .GE. are handled as procedure designators - // below. - switch (*intrinsicOp) { - case parser::DefinedOperator::IntrinsicOperator::Multiply: - [[fallthrough]]; - case parser::DefinedOperator::IntrinsicOperator::Add: - [[fallthrough]]; - case parser::DefinedOperator::IntrinsicOperator::Subtract: - ok = type.IsNumeric(TypeCategory::Integer) || - type.IsNumeric(TypeCategory::Real) || - type.IsNumeric(TypeCategory::Complex); - break; - - case parser::DefinedOperator::IntrinsicOperator::AND: - [[fallthrough]]; - case parser::DefinedOperator::IntrinsicOperator::OR: - [[fallthrough]]; - case parser::DefinedOperator::IntrinsicOperator::EQV: - [[fallthrough]]; - case parser::DefinedOperator::IntrinsicOperator::NEQV: - ok = IsLogical(type); - break; + auto checkOperator{[&](const parser::DefinedOperator &dOpr) { + if (const auto *intrinsicOp{ + std::get_if(&dOpr.u)}) { + // OMP5.2: The type [...] of a list item that appears in a + // reduction clause must be valid for the combiner expression + // See F2023: Table 10.2 + // .LT., .LE., .GT., .GE. are handled as procedure designators + // below. + switch (*intrinsicOp) { + case parser::DefinedOperator::IntrinsicOperator::Multiply: + case parser::DefinedOperator::IntrinsicOperator::Add: + case parser::DefinedOperator::IntrinsicOperator::Subtract: + return type.IsNumeric(TypeCategory::Integer) || + type.IsNumeric(TypeCategory::Real) || + type.IsNumeric(TypeCategory::Complex); + + case parser::DefinedOperator::IntrinsicOperator::AND: + case parser::DefinedOperator::IntrinsicOperator::OR: + case parser::DefinedOperator::IntrinsicOperator::EQV: + case parser::DefinedOperator::IntrinsicOperator::NEQV: + return isLogical(type); + + // Reduction identifier is not in OMP5.2 Table 5.2 + default: + DIE("This should have been caught in CheckIntrinsicOperator"); + return false; + } + } + return true; + }}; - // Reduction identifier is not in OMP5.2 Table 5.2 - default: - DIE("This should have been caught in CheckIntrinsicOperator"); - ok = false; - break; - } - } - }, - [&](const parser::ProcedureDesignator &procD) { - const parser::Name *name{std::get_if(&procD.u)}; - if (name && name->symbol) { - const SourceName &realName{name->symbol->GetUltimate().name()}; - // OMP5.2: The type [...] of a list item that appears in a - // reduction clause must be valid for the combiner expression - if (realName == "iand" || realName == "ior" || - realName == "ieor") { - // IAND: arguments must be integers: F2023 16.9.100 - // IEOR: arguments must be integers: F2023 16.9.106 - // IOR: arguments must be integers: F2023 16.9.111 - ok = type.IsNumeric(TypeCategory::Integer); - } else if (realName == "max" || realName == "min") { - // MAX: arguments must be integer, real, or character: - // F2023 16.9.135 - // MIN: arguments must be integer, real, or character: - // F2023 16.9.141 - ok = type.IsNumeric(TypeCategory::Integer) || - type.IsNumeric(TypeCategory::Real) || IsCharacter(type); - } - } - }, - }, - definedOp->u); + auto checkDesignator{[&](const parser::ProcedureDesignator &procD) { + const parser::Name *name{std::get_if(&procD.u)}; + if (name && name->symbol) { + const SourceName &realName{name->symbol->GetUltimate().name()}; + // OMP5.2: The type [...] of a list item that appears in a + // reduction clause must be valid for the combiner expression + if (realName == "iand" || realName == "ior" || realName == "ieor") { + // IAND: arguments must be integers: F2023 16.9.100 + // IEOR: arguments must be integers: F2023 16.9.106 + // IOR: arguments must be integers: F2023 16.9.111 + return type.IsNumeric(TypeCategory::Integer); + } else if (realName == "max" || realName == "min") { + // MAX: arguments must be integer, real, or character: + // F2023 16.9.135 + // MIN: arguments must be integer, real, or character: + // F2023 16.9.141 + return type.IsNumeric(TypeCategory::Integer) || + type.IsNumeric(TypeCategory::Real) || isCharacter(type); + } + } + // TODO: user defined reduction operators. Just allow everything for now. + return true; + }}; - return ok; + return common::visit( + common::visitors{checkOperator, checkDesignator}, ident.u); } -void OmpStructureChecker::CheckReductionTypeList( - const parser::OmpClause::Reduction &x) { - const auto &ompObjectList{std::get(x.v.t)}; - CheckIntentInPointerAndDefinable( - ompObjectList, llvm::omp::Clause::OMPC_reduction); - CheckReductionArraySection(ompObjectList); - // If this is a worksharing construct then ensure the reduction variable - // is not private in the parallel region that it binds to. - if (llvm::omp::nestedReduceWorkshareAllowedSet.test(GetContext().directive)) { - CheckSharedBindingInOuterContext(ompObjectList); - } - +void OmpStructureChecker::CheckReductionObjectTypes( + const parser::OmpObjectList &objects, + const parser::OmpReductionIdentifier &ident) { SymbolSourceMap symbols; - GetSymbolsInObjectList(ompObjectList, symbols); + GetSymbolsInObjectList(objects, symbols); + for (auto &[symbol, source] : symbols) { - if (IsProcedurePointer(*symbol)) { - context_.Say(source, - "A procedure pointer '%s' must not appear in a REDUCTION clause."_err_en_US, - symbol->name()); - } else if (!IsReductionAllowedForType(x, DEREF(symbol->GetType()))) { - context_.Say(source, - "The type of '%s' is incompatible with the reduction operator."_err_en_US, - symbol->name()); + if (auto *type{symbol->GetType()}) { + if (!IsReductionAllowedForType(ident, *type)) { + context_.Say(source, + "The type of '%s' is incompatible with the reduction operator."_err_en_US, + symbol->name()); + } + } else { + assert(IsProcedurePointer(*symbol) && "Unexpected symbol properties"); } } } @@ -3127,43 +3267,13 @@ void OmpStructureChecker::CheckReductionModifier( } } -void OmpStructureChecker::CheckIntentInPointerAndDefinable( - const parser::OmpObjectList &objectList, const llvm::omp::Clause clause) { - for (const auto &ompObject : objectList.v) { - if (const auto *name{parser::Unwrap(ompObject)}) { - if (const auto *symbol{name->symbol}) { - if (IsPointer(symbol->GetUltimate()) && - IsIntentIn(symbol->GetUltimate())) { - context_.Say(GetContext().clauseSource, - "Pointer '%s' with the INTENT(IN) attribute may not appear " - "in a %s clause"_err_en_US, - symbol->name(), - parser::ToUpperCaseLetters(getClauseName(clause).str())); - } else if (auto msg{WhyNotDefinable(name->source, - context_.FindScope(name->source), DefinabilityFlags{}, - *symbol)}) { - context_ - .Say(GetContext().clauseSource, - "Variable '%s' on the %s clause is not definable"_err_en_US, - symbol->name(), - parser::ToUpperCaseLetters(getClauseName(clause).str())) - .Attach(std::move(msg->set_severity(parser::Severity::Because))); - } - } - } - } -} - void OmpStructureChecker::CheckReductionArraySection( - const parser::OmpObjectList &ompObjectList) { + const parser::OmpObjectList &ompObjectList, llvm::omp::Clause clauseId) { for (const auto &ompObject : ompObjectList.v) { if (const auto *dataRef{parser::Unwrap(ompObject)}) { if (const auto *arrayElement{ parser::Unwrap(ompObject)}) { - if (arrayElement) { - CheckArraySection(*arrayElement, GetLastName(*dataRef), - llvm::omp::Clause::OMPC_reduction); - } + CheckArraySection(*arrayElement, GetLastName(*dataRef), clauseId); } } } @@ -3232,9 +3342,11 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Shared &x) { CheckIsVarPartOfAnotherVar(GetContext().clauseSource, x.v, "SHARED"); } void OmpStructureChecker::Enter(const parser::OmpClause::Private &x) { + SymbolSourceMap symbols; + GetSymbolsInObjectList(x.v, symbols); CheckAllowedClause(llvm::omp::Clause::OMPC_private); CheckIsVarPartOfAnotherVar(GetContext().clauseSource, x.v, "PRIVATE"); - CheckIntentInPointer(x.v, llvm::omp::Clause::OMPC_private); + CheckIntentInPointer(symbols, llvm::omp::Clause::OMPC_private); } void OmpStructureChecker::Enter(const parser::OmpClause::Nowait &x) { @@ -3541,15 +3653,95 @@ void OmpStructureChecker::Enter(const parser::OmpClause::If &x) { void OmpStructureChecker::Enter(const parser::OmpClause::Linear &x) { CheckAllowedClause(llvm::omp::Clause::OMPC_linear); + unsigned version{context_.langOptions().OpenMPVersion}; + llvm::omp::Directive dir{GetContext().directive}; + parser::CharBlock clauseSource{GetContext().clauseSource}; + const parser::OmpLinearModifier *linearMod{nullptr}; - // 2.7 Loop Construct Restriction - if ((llvm::omp::allDoSet | llvm::omp::allSimdSet) - .test(GetContext().directive)) { - if (std::holds_alternative(x.v.u)) { - context_.Say(GetContext().clauseSource, - "A modifier may not be specified in a LINEAR clause " - "on the %s directive"_err_en_US, - ContextDirectiveAsFortran()); + SymbolSourceMap symbols; + auto &objects{std::get(x.v.t)}; + GetSymbolsInObjectList(objects, symbols); + + auto CheckIntegerNoRef{[&](const Symbol *symbol, parser::CharBlock source) { + if (!symbol->GetType()->IsNumeric(TypeCategory::Integer)) { + auto &desc{OmpGetDescriptor()}; + context_.Say(source, + "The list item '%s' specified without the REF '%s' must be of INTEGER type"_err_en_US, + symbol->name(), desc.name.str()); + } + }}; + + if (OmpVerifyModifiers(x.v, llvm::omp::OMPC_linear, clauseSource, context_)) { + auto &modifiers{OmpGetModifiers(x.v)}; + linearMod = OmpGetUniqueModifier(modifiers); + if (linearMod) { + // 2.7 Loop Construct Restriction + if ((llvm::omp::allDoSet | llvm::omp::allSimdSet).test(dir)) { + context_.Say(clauseSource, + "A modifier may not be specified in a LINEAR clause on the %s directive"_err_en_US, + ContextDirectiveAsFortran()); + return; + } + + auto &desc{OmpGetDescriptor()}; + for (auto &[symbol, source] : symbols) { + if (linearMod->v != parser::OmpLinearModifier::Value::Ref) { + CheckIntegerNoRef(symbol, source); + } else { + if (!IsAllocatable(*symbol) && !IsAssumedShape(*symbol) && + !IsPolymorphic(*symbol)) { + context_.Say(source, + "The list item `%s` specified with the REF '%s' must be polymorphic variable, assumed-shape array, or a variable with the `ALLOCATABLE` attribute"_err_en_US, + symbol->name(), desc.name.str()); + } + } + if (linearMod->v == parser::OmpLinearModifier::Value::Ref || + linearMod->v == parser::OmpLinearModifier::Value::Uval) { + if (!IsDummy(*symbol) || IsValue(*symbol)) { + context_.Say(source, + "If the `%s` is REF or UVAL, the list item '%s' must be a dummy argument without the VALUE attribute"_err_en_US, + desc.name.str(), symbol->name()); + } + } + } // for (symbol, source) + + if (version >= 52 && !std::get(x.v.t)) { + context_.Say(OmpGetModifierSource(modifiers, linearMod), + "The 'modifier()' syntax is deprecated in %s, use ' : modifier' instead"_warn_en_US, + ThisVersion(version)); + } + } + } + + // OpenMP 5.2: Ordered clause restriction + if (const auto *clause{ + FindClause(GetContext(), llvm::omp::Clause::OMPC_ordered)}) { + const auto &orderedClause{std::get(clause->u)}; + if (orderedClause.v) { + return; + } + } + + // OpenMP 5.2: Linear clause Restrictions + for (auto &[symbol, source] : symbols) { + if (!linearMod) { + // Already checked this with the modifier present. + CheckIntegerNoRef(symbol, source); + } + if (dir == llvm::omp::Directive::OMPD_declare_simd && !IsDummy(*symbol)) { + context_.Say(source, + "The list item `%s` must be a dummy argument"_err_en_US, + symbol->name()); + } + if (IsPointer(*symbol) || symbol->test(Symbol::Flag::CrayPointer)) { + context_.Say(source, + "The list item `%s` in a LINEAR clause must not be Cray Pointer or a variable with POINTER attribute"_err_en_US, + symbol->name()); + } + if (FindCommonBlockContaining(*symbol)) { + context_.Say(source, + "'%s' is a common block name and must not appear in an LINEAR clause"_err_en_US, + symbol->name()); } } } @@ -3891,11 +4083,11 @@ void OmpStructureChecker::CheckCopyingPolymorphicAllocatable( void OmpStructureChecker::Enter(const parser::OmpClause::Copyprivate &x) { CheckAllowedClause(llvm::omp::Clause::OMPC_copyprivate); - CheckIntentInPointer(x.v, llvm::omp::Clause::OMPC_copyprivate); - SymbolSourceMap currSymbols; - GetSymbolsInObjectList(x.v, currSymbols); + SymbolSourceMap symbols; + GetSymbolsInObjectList(x.v, symbols); + CheckIntentInPointer(symbols, llvm::omp::Clause::OMPC_copyprivate); CheckCopyingPolymorphicAllocatable( - currSymbols, llvm::omp::Clause::OMPC_copyprivate); + symbols, llvm::omp::Clause::OMPC_copyprivate); if (GetContext().directive == llvm::omp::Directive::OMPD_single) { context_.Say(GetContext().clauseSource, "%s clause is not allowed on the OMP %s directive," @@ -3945,29 +4137,28 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Copyin &x) { currSymbols, llvm::omp::Clause::OMPC_copyin); } -void OmpStructureChecker::CheckStructureElement( - const parser::OmpObjectList &ompObjectList, - const llvm::omp::Clause clause) { - for (const auto &ompObject : ompObjectList.v) { +void OmpStructureChecker::CheckStructureComponent( + const parser::OmpObjectList &objects, llvm::omp::Clause clauseId) { + auto CheckComponent{[&](const parser::Designator &designator) { + if (auto *dataRef{std::get_if(&designator.u)}) { + if (!IsDataRefTypeParamInquiry(dataRef)) { + if (auto *comp{parser::Unwrap(*dataRef)}) { + context_.Say(comp->component.source, + "A variable that is part of another variable cannot appear on the %s clause"_err_en_US, + parser::ToUpperCaseLetters(getClauseName(clauseId).str())); + } + } + } + }}; + + for (const auto &object : objects.v) { common::visit( common::visitors{ - [&](const parser::Designator &designator) { - if (std::get_if(&designator.u)) { - if (parser::Unwrap(ompObject)) { - context_.Say(GetContext().clauseSource, - "A variable that is part of another variable " - "(structure element) cannot appear on the %s " - "%s clause"_err_en_US, - ContextDirectiveAsFortran(), - parser::ToUpperCaseLetters(getClauseName(clause).str())); - } - } - }, + CheckComponent, [&](const parser::Name &name) {}, }, - ompObject.u); + object.u); } - return; } void OmpStructureChecker::Enter(const parser::OmpClause::Update &x) { @@ -4009,7 +4200,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::Update &x) { } void OmpStructureChecker::Enter(const parser::OmpClause::UseDevicePtr &x) { - CheckStructureElement(x.v, llvm::omp::Clause::OMPC_use_device_ptr); + CheckStructureComponent(x.v, llvm::omp::Clause::OMPC_use_device_ptr); CheckAllowedClause(llvm::omp::Clause::OMPC_use_device_ptr); SymbolSourceMap currSymbols; GetSymbolsInObjectList(x.v, currSymbols); @@ -4038,7 +4229,7 @@ void OmpStructureChecker::Enter(const parser::OmpClause::UseDevicePtr &x) { } void OmpStructureChecker::Enter(const parser::OmpClause::UseDeviceAddr &x) { - CheckStructureElement(x.v, llvm::omp::Clause::OMPC_use_device_addr); + CheckStructureComponent(x.v, llvm::omp::Clause::OMPC_use_device_addr); CheckAllowedClause(llvm::omp::Clause::OMPC_use_device_addr); SymbolSourceMap currSymbols; GetSymbolsInObjectList(x.v, currSymbols); @@ -4205,6 +4396,17 @@ void OmpStructureChecker::Enter(const parser::OmpClause::To &x) { } } +void OmpStructureChecker::Enter(const parser::OmpClause::OmpxBare &x) { + // Don't call CheckAllowedClause, because it allows "ompx_bare" on + // a non-combined "target" directive (for reasons of splitting combined + // directives). In source code it's only allowed on "target teams". + if (GetContext().directive != llvm::omp::Directive::OMPD_target_teams) { + context_.Say(GetContext().clauseSource, + "%s clause is only allowed on combined TARGET TEAMS"_err_en_US, + parser::ToUpperCaseLetters(getClauseName(llvm::omp::OMPC_ompx_bare))); + } +} + llvm::StringRef OmpStructureChecker::getClauseName(llvm::omp::Clause clause) { return llvm::omp::getOpenMPClauseName(clause); } @@ -4214,6 +4416,26 @@ llvm::StringRef OmpStructureChecker::getDirectiveName( return llvm::omp::getOpenMPDirectiveName(directive); } +const Symbol *OmpStructureChecker::GetObjectSymbol( + const parser::OmpObject &object) { + if (auto *name{std::get_if(&object.u)}) { + return &name->symbol->GetUltimate(); + } else if (auto *desg{std::get_if(&object.u)}) { + return &GetLastName(*desg).symbol->GetUltimate(); + } + return nullptr; +} + +std::optional OmpStructureChecker::GetObjectSource( + const parser::OmpObject &object) { + if (auto *name{std::get_if(&object.u)}) { + return name->source; + } else if (auto *desg{std::get_if(&object.u)}) { + return GetLastName(*desg).source; + } + return std::nullopt; +} + void OmpStructureChecker::CheckDependList(const parser::DataRef &d) { common::visit( common::visitors{ @@ -4267,15 +4489,6 @@ void OmpStructureChecker::CheckArraySection( "DEPEND " "clause"_err_en_US); } - const auto stride{GetIntValue(strideExpr)}; - if ((stride && stride != 1)) { - context_.Say(GetContext().clauseSource, - "A list item that appears in a REDUCTION clause" - " should have a contiguous storage array " - "section."_err_en_US, - ContextDirectiveAsFortran()); - break; - } } } } @@ -4286,14 +4499,23 @@ void OmpStructureChecker::CheckArraySection( } void OmpStructureChecker::CheckIntentInPointer( - const parser::OmpObjectList &objectList, const llvm::omp::Clause clause) { - SymbolSourceMap symbols; - GetSymbolsInObjectList(objectList, symbols); + SymbolSourceMap &symbols, llvm::omp::Clause clauseId) { for (auto &[symbol, source] : symbols) { if (IsPointer(*symbol) && IsIntentIn(*symbol)) { context_.Say(source, - "Pointer '%s' with the INTENT(IN) attribute may not appear " - "in a %s clause"_err_en_US, + "Pointer '%s' with the INTENT(IN) attribute may not appear in a %s clause"_err_en_US, + symbol->name(), + parser::ToUpperCaseLetters(getClauseName(clauseId).str())); + } + } +} + +void OmpStructureChecker::CheckProcedurePointer( + SymbolSourceMap &symbols, llvm::omp::Clause clause) { + for (const auto &[symbol, source] : symbols) { + if (IsProcedurePointer(*symbol)) { + context_.Say(source, + "Procedure pointer '%s' may not appear in a %s clause"_err_en_US, symbol->name(), parser::ToUpperCaseLetters(getClauseName(clause).str())); } @@ -4468,7 +4690,7 @@ void OmpStructureChecker::CheckIfContiguous(const parser::OmpObject &object) { const parser::Name *name{GetObjectName(object)}; assert(name && "Expecting name component"); context_.Say(name->source, - "Reference to %s must be a contiguous object"_err_en_US, + "Reference to '%s' must be a contiguous object"_err_en_US, name->ToString()); } } diff --git a/flang/lib/Semantics/check-omp-structure.h b/flang/lib/Semantics/check-omp-structure.h index 1411a9271d466..346a7bed9138f 100644 --- a/flang/lib/Semantics/check-omp-structure.h +++ b/flang/lib/Semantics/check-omp-structure.h @@ -102,6 +102,8 @@ class OmpStructureChecker void Enter(const parser::OmpDeclareTargetWithList &); void Enter(const parser::OmpDeclareTargetWithClause &); void Leave(const parser::OmpDeclareTargetWithClause &); + void Enter(const parser::OpenMPErrorConstruct &); + void Leave(const parser::OpenMPErrorConstruct &); void Enter(const parser::OpenMPExecutableAllocate &); void Leave(const parser::OpenMPExecutableAllocate &); void Enter(const parser::OpenMPAllocatorsConstruct &); @@ -142,17 +144,22 @@ class OmpStructureChecker #define GEN_FLANG_CLAUSE_CHECK_ENTER #include "llvm/Frontend/OpenMP/OMP.inc" + void Leave(const parser::OmpClause::Fail &); + void Enter(const parser::OmpFailClause &); + void Leave(const parser::OmpFailClause &); + private: bool CheckAllowedClause(llvmOmpClause clause); bool IsVariableListItem(const Symbol &sym); bool IsExtendedListItem(const Symbol &sym); + bool IsCommonBlock(const Symbol &sym); std::optional IsContiguous(const parser::OmpObject &object); void CheckMultipleOccurrence(semantics::UnorderedSymbolSet &listVars, const std::list &nameList, const parser::CharBlock &item, const std::string &clauseName); void CheckMultListItems(); - void CheckStructureElement(const parser::OmpObjectList &ompObjectList, - const llvm::omp::Clause clause); + void CheckStructureComponent( + const parser::OmpObjectList &objects, llvm::omp::Clause clauseId); bool HasInvalidWorksharingNesting( const parser::CharBlock &, const OmpDirectiveSet &); bool IsCloselyNestedRegion(const OmpDirectiveSet &set); @@ -171,6 +178,9 @@ class OmpStructureChecker typename IterTy = decltype(std::declval().begin())> std::optional FindDuplicate(RangeTy &&); + const Symbol *GetObjectSymbol(const parser::OmpObject &object); + std::optional GetObjectSource( + const parser::OmpObject &object); void CheckDependList(const parser::DataRef &); void CheckDependArraySection( const common::Indirection &, const parser::Name &); @@ -182,8 +192,8 @@ class OmpStructureChecker const parser::OmpObjectList &objList); void CheckSymbolNames( const parser::CharBlock &source, const parser::OmpObjectList &objList); - void CheckIntentInPointer( - const parser::OmpObjectList &, const llvm::omp::Clause); + void CheckIntentInPointer(SymbolSourceMap &, const llvm::omp::Clause); + void CheckProcedurePointer(SymbolSourceMap &, const llvm::omp::Clause); void GetSymbolsInObjectList(const parser::OmpObjectList &, SymbolSourceMap &); void CheckDefinableObjects(SymbolSourceMap &, const llvm::omp::Clause); void CheckCopyingPolymorphicAllocatable( @@ -220,10 +230,12 @@ class OmpStructureChecker void CheckCancellationNest( const parser::CharBlock &source, const parser::OmpCancelType::Type &type); std::int64_t GetOrdCollapseLevel(const parser::OpenMPLoopConstruct &x); - bool CheckReductionOperators(const parser::OmpClause::Reduction &); - bool CheckIntrinsicOperator( - const parser::DefinedOperator::IntrinsicOperator &); - void CheckReductionTypeList(const parser::OmpClause::Reduction &); + void CheckReductionObjects( + const parser::OmpObjectList &objects, llvm::omp::Clause clauseId); + bool CheckReductionOperator(const parser::OmpReductionIdentifier &ident, + parser::CharBlock source, llvm::omp::Clause clauseId); + void CheckReductionObjectTypes(const parser::OmpObjectList &objects, + const parser::OmpReductionIdentifier &ident); void CheckReductionModifier(const parser::OmpReductionModifier &); void CheckMasterNesting(const parser::OpenMPBlockConstruct &x); void ChecksOnOrderedAsBlock(); @@ -231,9 +243,8 @@ class OmpStructureChecker void CheckScan(const parser::OpenMPSimpleStandaloneConstruct &x); void ChecksOnOrderedAsStandalone(); void CheckOrderedDependClause(std::optional orderedValue); - void CheckReductionArraySection(const parser::OmpObjectList &ompObjectList); - void CheckIntentInPointerAndDefinable( - const parser::OmpObjectList &, const llvm::omp::Clause); + void CheckReductionArraySection( + const parser::OmpObjectList &ompObjectList, llvm::omp::Clause clauseId); void CheckArraySection(const parser::ArrayElement &arrayElement, const parser::Name &name, const llvm::omp::Clause clause); void CheckSharedBindingInOuterContext( @@ -272,6 +283,7 @@ class OmpStructureChecker using LoopConstruct = std::variant; std::vector loopStack_; + bool isFailClause{false}; }; /// Find a duplicate entry in the range, and return an iterator to it. diff --git a/flang/lib/Semantics/compute-offsets.cpp b/flang/lib/Semantics/compute-offsets.cpp index 028633813a91b..94640fa30baa5 100644 --- a/flang/lib/Semantics/compute-offsets.cpp +++ b/flang/lib/Semantics/compute-offsets.cpp @@ -11,7 +11,7 @@ #include "flang/Evaluate/fold.h" #include "flang/Evaluate/shape.h" #include "flang/Evaluate/type.h" -#include "flang/Runtime/descriptor.h" +#include "flang/Runtime/descriptor-consts.h" #include "flang/Semantics/scope.h" #include "flang/Semantics/semantics.h" #include "flang/Semantics/symbol.h" @@ -339,8 +339,12 @@ auto ComputeOffsetsHelper::GetSizeAndAlignment( const auto *derived{evaluate::GetDerivedTypeSpec(dyType)}; int lenParams{derived ? CountLenParameters(*derived) : 0}; bool needAddendum{derived || (dyType && dyType->IsUnlimitedPolymorphic())}; - std::size_t size{runtime::Descriptor::SizeInBytes( + + // FIXME: Get descriptor size from targetCharacteristics instead + // overapproximation + std::size_t size{runtime::MaxDescriptorSizeInBytes( symbol.Rank(), needAddendum, lenParams)}; + return {size, targetCharacteristics.descriptorAlignment()}; } if (IsProcedurePointer(symbol)) { diff --git a/flang/lib/Semantics/openmp-modifiers.cpp b/flang/lib/Semantics/openmp-modifiers.cpp index f8f81e6c6ffa1..9f2896229bb7f 100644 --- a/flang/lib/Semantics/openmp-modifiers.cpp +++ b/flang/lib/Semantics/openmp-modifiers.cpp @@ -407,6 +407,39 @@ const OmpModifierDescriptor &OmpGetDescriptor() { return desc; } +template <> +const OmpModifierDescriptor & +OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"step-complex-modifier", + /*props=*/ + { + {52, {OmpProperty::Unique}}, + }, + /*clauses=*/ + { + {52, {Clause::OMPC_linear}}, + }, + }; + return desc; +} + +template <> +const OmpModifierDescriptor &OmpGetDescriptor() { + static const OmpModifierDescriptor desc{ + /*name=*/"step-simple-modifier", + /*props=*/ + { + {45, {OmpProperty::Unique, OmpProperty::Exclusive}}, + }, + /*clauses=*/ + { + {45, {Clause::OMPC_linear}}, + }, + }; + return desc; +} + template <> const OmpModifierDescriptor &OmpGetDescriptor() { static const OmpModifierDescriptor desc{ diff --git a/flang/lib/Semantics/resolve-directives.cpp b/flang/lib/Semantics/resolve-directives.cpp index 80a086acebba2..39478b58a9070 100644 --- a/flang/lib/Semantics/resolve-directives.cpp +++ b/flang/lib/Semantics/resolve-directives.cpp @@ -502,19 +502,8 @@ class OmpAttributeVisitor : DirectiveAttributeVisitor { return false; } bool Pre(const parser::OmpLinearClause &x) { - common::visit(common::visitors{ - [&](const parser::OmpLinearClause::WithoutModifier - &linearWithoutModifier) { - ResolveOmpNameList(linearWithoutModifier.names, - Symbol::Flag::OmpLinear); - }, - [&](const parser::OmpLinearClause::WithModifier - &linearWithModifier) { - ResolveOmpNameList( - linearWithModifier.names, Symbol::Flag::OmpLinear); - }, - }, - x.u); + auto &objects{std::get(x.t)}; + ResolveOmpObjectList(objects, Symbol::Flag::OmpLinear); return false; } diff --git a/flang/lib/Semantics/resolve-names.cpp b/flang/lib/Semantics/resolve-names.cpp index b576f59e8c7e5..3a1ccec1fdf4b 100644 --- a/flang/lib/Semantics/resolve-names.cpp +++ b/flang/lib/Semantics/resolve-names.cpp @@ -8953,6 +8953,18 @@ void ResolveNamesVisitor::FinishSpecificationPart( misparsedStmtFuncFound_ = false; funcResultStack().CompleteFunctionResultType(); CheckImports(); + bool inDeviceSubprogram = false; + if (auto *subp{currScope().symbol() + ? currScope().symbol()->detailsIf() + : nullptr}) { + if (auto attrs{subp->cudaSubprogramAttrs()}) { + if (*attrs == common::CUDASubprogramAttrs::Device || + *attrs == common::CUDASubprogramAttrs::Global || + *attrs == common::CUDASubprogramAttrs::Grid_Global) { + inDeviceSubprogram = true; + } + } + } for (auto &pair : currScope()) { auto &symbol{*pair.second}; if (inInterfaceBlock()) { @@ -8961,6 +8973,14 @@ void ResolveNamesVisitor::FinishSpecificationPart( if (NeedsExplicitType(symbol)) { ApplyImplicitRules(symbol); } + if (inDeviceSubprogram && IsDummy(symbol) && + symbol.has()) { + auto *dummy{symbol.detailsIf()}; + if (!dummy->cudaDataAttr() && !IsValue(symbol)) { + // Implicitly set device attribute if none is set in device context. + dummy->set_cudaDataAttr(common::CUDADataAttr::Device); + } + } if (IsDummy(symbol) && isImplicitNoneType() && symbol.test(Symbol::Flag::Implicit) && !context().HasError(symbol)) { Say(symbol.name(), diff --git a/flang/runtime/CMakeLists.txt b/flang/runtime/CMakeLists.txt index 0ad1b718d5875..d0396164d79a7 100644 --- a/flang/runtime/CMakeLists.txt +++ b/flang/runtime/CMakeLists.txt @@ -59,6 +59,11 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) ) endif() +# function checks +find_package(Backtrace) +set(HAVE_BACKTRACE ${Backtrace_FOUND}) +set(BACKTRACE_HEADER ${Backtrace_HEADER}) + include(CheckCXXSymbolExists) include(CheckCXXSourceCompiles) check_cxx_symbol_exists(strerror_r string.h HAVE_STRERROR_R) diff --git a/flang/runtime/CUDA/allocatable.cpp b/flang/runtime/CUDA/allocatable.cpp index 3f6f8f3d6d5de..9be54e8906903 100644 --- a/flang/runtime/CUDA/allocatable.cpp +++ b/flang/runtime/CUDA/allocatable.cpp @@ -52,7 +52,7 @@ int RTDEF(CUFAllocatableAllocate)(Descriptor &desc, int64_t stream, } // Perform the standard allocation. int stat{RTNAME(AllocatableAllocate)( - desc, stream, hasStat, errMsg, sourceFile, sourceLine)}; + desc, hasStat, errMsg, sourceFile, sourceLine)}; return stat; } diff --git a/flang/runtime/CUDA/allocator.cpp b/flang/runtime/CUDA/allocator.cpp index e41ed77e40ff9..85b3daf65a8ba 100644 --- a/flang/runtime/CUDA/allocator.cpp +++ b/flang/runtime/CUDA/allocator.cpp @@ -33,8 +33,7 @@ void RTDEF(CUFRegisterAllocator)() { } } -void *CUFAllocPinned( - std::size_t sizeInBytes, [[maybe_unused]] std::int64_t asyncId) { +void *CUFAllocPinned(std::size_t sizeInBytes) { void *p; CUDA_REPORT_IF_ERROR(cudaMallocHost((void **)&p, sizeInBytes)); return p; @@ -42,8 +41,7 @@ void *CUFAllocPinned( void CUFFreePinned(void *p) { CUDA_REPORT_IF_ERROR(cudaFreeHost(p)); } -void *CUFAllocDevice( - std::size_t sizeInBytes, [[maybe_unused]] std::int64_t asyncId) { +void *CUFAllocDevice(std::size_t sizeInBytes) { void *p; CUDA_REPORT_IF_ERROR(cudaMalloc(&p, sizeInBytes)); return p; @@ -51,8 +49,7 @@ void *CUFAllocDevice( void CUFFreeDevice(void *p) { CUDA_REPORT_IF_ERROR(cudaFree(p)); } -void *CUFAllocManaged( - std::size_t sizeInBytes, [[maybe_unused]] std::int64_t asyncId) { +void *CUFAllocManaged(std::size_t sizeInBytes) { void *p; CUDA_REPORT_IF_ERROR( cudaMallocManaged((void **)&p, sizeInBytes, cudaMemAttachGlobal)); @@ -61,10 +58,9 @@ void *CUFAllocManaged( void CUFFreeManaged(void *p) { CUDA_REPORT_IF_ERROR(cudaFree(p)); } -void *CUFAllocUnified( - std::size_t sizeInBytes, [[maybe_unused]] std::int64_t asyncId) { +void *CUFAllocUnified(std::size_t sizeInBytes) { // Call alloc managed for the time being. - return CUFAllocManaged(sizeInBytes, asyncId); + return CUFAllocManaged(sizeInBytes); } void CUFFreeUnified(void *p) { diff --git a/flang/runtime/CUDA/descriptor.cpp b/flang/runtime/CUDA/descriptor.cpp index f1feb00941aa8..58bc0dbed6bab 100644 --- a/flang/runtime/CUDA/descriptor.cpp +++ b/flang/runtime/CUDA/descriptor.cpp @@ -10,6 +10,7 @@ #include "../terminator.h" #include "flang/Runtime/CUDA/allocator.h" #include "flang/Runtime/CUDA/common.h" +#include "flang/Runtime/descriptor.h" #include "cuda_runtime.h" @@ -19,8 +20,7 @@ RT_EXT_API_GROUP_BEGIN Descriptor *RTDEF(CUFAllocDesciptor)( std::size_t sizeInBytes, const char *sourceFile, int sourceLine) { - return reinterpret_cast( - CUFAllocManaged(sizeInBytes, kCudaNoStream)); + return reinterpret_cast(CUFAllocManaged(sizeInBytes)); } void RTDEF(CUFFreeDesciptor)( diff --git a/flang/runtime/allocatable.cpp b/flang/runtime/allocatable.cpp index b65cec8d51cf8..5e065f47636a8 100644 --- a/flang/runtime/allocatable.cpp +++ b/flang/runtime/allocatable.cpp @@ -133,17 +133,15 @@ void RTDEF(AllocatableApplyMold)( } } -int RTDEF(AllocatableAllocate)(Descriptor &descriptor, std::int64_t asyncId, - bool hasStat, const Descriptor *errMsg, const char *sourceFile, - int sourceLine) { +int RTDEF(AllocatableAllocate)(Descriptor &descriptor, bool hasStat, + const Descriptor *errMsg, const char *sourceFile, int sourceLine) { Terminator terminator{sourceFile, sourceLine}; if (!descriptor.IsAllocatable()) { return ReturnError(terminator, StatInvalidDescriptor, errMsg, hasStat); } else if (descriptor.IsAllocated()) { return ReturnError(terminator, StatBaseNotNull, errMsg, hasStat); } else { - int stat{ - ReturnError(terminator, descriptor.Allocate(asyncId), errMsg, hasStat)}; + int stat{ReturnError(terminator, descriptor.Allocate(), errMsg, hasStat)}; if (stat == StatOk) { if (const DescriptorAddendum * addendum{descriptor.Addendum()}) { if (const auto *derived{addendum->derivedType()}) { @@ -162,7 +160,7 @@ int RTDEF(AllocatableAllocateSource)(Descriptor &alloc, const Descriptor &source, bool hasStat, const Descriptor *errMsg, const char *sourceFile, int sourceLine) { int stat{RTNAME(AllocatableAllocate)( - alloc, /*asyncId=*/-1, hasStat, errMsg, sourceFile, sourceLine)}; + alloc, hasStat, errMsg, sourceFile, sourceLine)}; if (stat == StatOk) { Terminator terminator{sourceFile, sourceLine}; DoFromSourceAssign(alloc, source, terminator); diff --git a/flang/runtime/array-constructor.cpp b/flang/runtime/array-constructor.cpp index 786fb2703053b..de124a018c790 100644 --- a/flang/runtime/array-constructor.cpp +++ b/flang/runtime/array-constructor.cpp @@ -50,8 +50,8 @@ static RT_API_ATTRS void AllocateOrReallocateVectorIfNeeded( initialAllocationSize(fromElements, to.ElementBytes())}; to.GetDimension(0).SetBounds(1, allocationSize); RTNAME(AllocatableAllocate) - (to, /*asyncId=*/-1, /*hasStat=*/false, /*errMsg=*/nullptr, - vector.sourceFile, vector.sourceLine); + (to, /*hasStat=*/false, /*errMsg=*/nullptr, vector.sourceFile, + vector.sourceLine); to.GetDimension(0).SetBounds(1, fromElements); vector.actualAllocationSize = allocationSize; } else { @@ -59,8 +59,8 @@ static RT_API_ATTRS void AllocateOrReallocateVectorIfNeeded( // first value: there should be no reallocation. RUNTIME_CHECK(terminator, previousToElements >= fromElements); RTNAME(AllocatableAllocate) - (to, /*asyncId=*/-1, /*hasStat=*/false, /*errMsg=*/nullptr, - vector.sourceFile, vector.sourceLine); + (to, /*hasStat=*/false, /*errMsg=*/nullptr, vector.sourceFile, + vector.sourceLine); vector.actualAllocationSize = previousToElements; } } else { @@ -92,13 +92,10 @@ extern "C" { RT_EXT_API_GROUP_BEGIN void RTDEF(InitArrayConstructorVector)(ArrayConstructorVector &vector, - Descriptor &to, bool useValueLengthParameters, int vectorClassSize, - const char *sourceFile, int sourceLine) { + Descriptor &to, bool useValueLengthParameters, const char *sourceFile, + int sourceLine) { Terminator terminator{vector.sourceFile, vector.sourceLine}; - RUNTIME_CHECK(terminator, - to.rank() == 1 && - sizeof(ArrayConstructorVector) <= - static_cast(vectorClassSize)); + RUNTIME_CHECK(terminator, to.rank() == 1); SubscriptValue actualAllocationSize{ to.IsAllocated() ? static_cast(to.Elements()) : 0}; (void)new (&vector) ArrayConstructorVector{to, /*nextValuePosition=*/0, diff --git a/flang/runtime/config.h.cmake b/flang/runtime/config.h.cmake index 0a1d1394b9bc4..a2271be77b8c6 100644 --- a/flang/runtime/config.h.cmake +++ b/flang/runtime/config.h.cmake @@ -8,4 +8,9 @@ don't. */ #cmakedefine01 HAVE_DECL_STRERROR_S +/* Define to 1 if you have the `backtrace' function. */ +#cmakedefine HAVE_BACKTRACE ${HAVE_BACKTRACE} + +#define BACKTRACE_HEADER <${BACKTRACE_HEADER}> + #endif diff --git a/flang/runtime/descriptor.cpp b/flang/runtime/descriptor.cpp index c6aa916f03d81..eaf6331ef8e84 100644 --- a/flang/runtime/descriptor.cpp +++ b/flang/runtime/descriptor.cpp @@ -163,7 +163,7 @@ RT_API_ATTRS static inline int MapAllocIdx(const Descriptor &desc) { #endif } -RT_API_ATTRS int Descriptor::Allocate(std::int64_t asyncId) { +RT_API_ATTRS int Descriptor::Allocate() { std::size_t elementBytes{ElementBytes()}; if (static_cast(elementBytes) < 0) { // F'2023 7.4.4.2 p5: "If the character length parameter value evaluates @@ -175,7 +175,7 @@ RT_API_ATTRS int Descriptor::Allocate(std::int64_t asyncId) { // Zero size allocation is possible in Fortran and the resulting // descriptor must be allocated/associated. Since std::malloc(0) // result is implementation defined, always allocate at least one byte. - void *p{alloc(byteSize ? byteSize : 1, asyncId)}; + void *p{alloc(byteSize ? byteSize : 1)}; if (!p) { return CFI_ERROR_MEM_ALLOCATION; } diff --git a/flang/runtime/environment-default-list.h b/flang/runtime/environment-default-list.h old mode 100755 new mode 100644 diff --git a/flang/runtime/internal-unit.cpp b/flang/runtime/internal-unit.cpp index 0a10bc05a4a7a..5f9cfc89b70dc 100644 --- a/flang/runtime/internal-unit.cpp +++ b/flang/runtime/internal-unit.cpp @@ -36,6 +36,8 @@ RT_API_ATTRS InternalDescriptorUnit::InternalDescriptorUnit( Descriptor &d{descriptor()}; RUNTIME_CHECK( terminator, that.SizeInBytes() <= d.SizeInBytes(maxRank, true, 0)); + RUNTIME_CHECK(terminator, + that.SizeInBytes() <= MaxDescriptorSizeInBytes(maxRank, true, 0)); new (&d) Descriptor{that}; d.Check(); internalIoCharKind = thatType->second; diff --git a/flang/runtime/stop.cpp b/flang/runtime/stop.cpp index cfb36b4084020..f8457e10566a2 100644 --- a/flang/runtime/stop.cpp +++ b/flang/runtime/stop.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "flang/Runtime/stop.h" +#include "config.h" #include "environment.h" #include "file.h" #include "io-error.h" @@ -16,6 +17,10 @@ #include #include +#ifdef HAVE_BACKTRACE +#include BACKTRACE_HEADER +#endif + extern "C" { static void DescribeIEEESignaledExceptions() { @@ -152,11 +157,37 @@ void RTNAME(PauseStatementText)(const char *code, std::size_t length) { std::exit(status); } +static void PrintBacktrace() { +#ifdef HAVE_BACKTRACE + // TODO: Need to parse DWARF information to print function line numbers + constexpr int MAX_CALL_STACK{999}; + void *buffer[MAX_CALL_STACK]; + int nptrs{backtrace(buffer, MAX_CALL_STACK)}; + + if (char **symbols{backtrace_symbols(buffer, nptrs)}) { + for (int i = 0; i < nptrs; i++) { + Fortran::runtime::Terminator{}.PrintCrashArgs("#%d %s\n", i, symbols[i]); + } + free(symbols); + } + +#else + + // TODO: Need to implement the version for other platforms. + Fortran::runtime::Terminator{}.PrintCrashArgs("backtrace is not supported."); + +#endif +} + [[noreturn]] void RTNAME(Abort)() { - // TODO: Add backtrace call, unless with `-fno-backtrace`. +#ifdef HAVE_BACKTRACE + PrintBacktrace(); +#endif std::abort(); } +void FORTRAN_PROCEDURE_NAME(backtrace)() { PrintBacktrace(); } + [[noreturn]] void RTNAME(ReportFatalUserError)( const char *message, const char *source, int line) { Fortran::runtime::Terminator{source, line}.Crash(message); diff --git a/flang/test/Driver/Inputs/config-l.cfg b/flang/test/Driver/Inputs/config-l.cfg new file mode 100644 index 0000000000000..8cc3abf166adf --- /dev/null +++ b/flang/test/Driver/Inputs/config-l.cfg @@ -0,0 +1,3 @@ +-ffast-math $-lm +-Wl,--as-needed $-Wl,-Bstatic +$-lhappy $-Wl,-Bdynamic diff --git a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 b/flang/test/Driver/bbc-mlir-pass-pipeline.f90 index 1f09e7ad4c2f5..5520d750e2ce1 100644 --- a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 +++ b/flang/test/Driver/bbc-mlir-pass-pipeline.f90 @@ -17,14 +17,12 @@ ! CHECK-NEXT: (S) 0 num-cse'd - Number of operations CSE'd ! CHECK-NEXT: (S) 0 num-dce'd - Number of operations DCE'd -! CHECK-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +! CHECK-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] ! CHECK-NEXT: 'fir.global' Pipeline ! CHECK-NEXT: CharacterConversion ! CHECK-NEXT: 'func.func' Pipeline ! CHECK-NEXT: ArrayValueCopy ! CHECK-NEXT: CharacterConversion -! CHECK-NEXT: 'gpu.module' Pipeline -! CHECK-NEXT: CharacterConversion ! CHECK-NEXT: 'omp.declare_reduction' Pipeline ! CHECK-NEXT: CharacterConversion ! CHECK-NEXT: 'omp.private' Pipeline @@ -50,16 +48,13 @@ ! CHECK-NEXT: PolymorphicOpConversion ! CHECK-NEXT: AssumedRankOpConversion -! CHECK-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +! CHECK-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] ! CHECK-NEXT: 'fir.global' Pipeline ! CHECK-NEXT: StackReclaim ! CHECK-NEXT: CFGConversion ! CHECK-NEXT: 'func.func' Pipeline ! CHECK-NEXT: StackReclaim ! CHECK-NEXT: CFGConversion -! CHECK-NEXT: 'gpu.module' Pipeline -! CHECK-NEXT: StackReclaim -! CHECK-NEXT: CFGConversion ! CHECK-NEXT: 'omp.declare_reduction' Pipeline ! CHECK-NEXT: StackReclaim ! CHECK-NEXT: CFGConversion diff --git a/flang/test/Driver/config-file.f90 b/flang/test/Driver/config-file.f90 index 70316dd971f36..6991fda9bd483 100644 --- a/flang/test/Driver/config-file.f90 +++ b/flang/test/Driver/config-file.f90 @@ -61,3 +61,29 @@ ! CHECK-TWO-CONFIGS-NEXT: Configuration file: {{.*}}Inputs{{.}}config2{{.}}config-4.cfg ! CHECK-TWO-CONFIGS: -ffp-contract=fast ! CHECK-TWO-CONFIGS: -O3 + +!--- The linker input flags should be moved to the end of input list and appear only when linking. +! RUN: %flang --target=aarch64-unknown-linux-gnu --config %S/Inputs/config-l.cfg %s -lmylib -Wl,foo.a -### 2>&1 | FileCheck %s -check-prefix CHECK-LINKING +! RUN: %flang --target=aarch64-unknown-linux-gnu --config %S/Inputs/config-l.cfg -fopenmp=libomp %s -lmylib -Wl,foo.a -### 2>&1 | FileCheck %s -check-prefix CHECK-LINKING-LIBOMP-GOES-AFTER +! RUN: %flang --target=aarch64-unknown-linux-gnu --config %S/Inputs/config-l.cfg -S %s -### 2>&1 | FileCheck %s -check-prefix CHECK-NOLINKING +! RUN: %flang --target=aarch64-unknown-linux-gnu --config %S/Inputs/config-l.cfg -fopenmp=libomp -S %s -### 2>&1 | FileCheck %s -check-prefix CHECK-NOLINKING-OPENMP +! RUN: %flang --target=x86_64-pc-windows-msvc --config %S/Inputs/config-l.cfg %s -lmylib -Wl,foo.lib -### 2>&1 | FileCheck %s -check-prefix CHECK-LINKING-MSVC +! RUN: %flang --target=x86_64-pc-windows-msvc --config %S/Inputs/config-l.cfg -S %s -### 2>&1 | FileCheck %s -check-prefix CHECK-NOLINKING-MSVC +! CHECK-LINKING: Configuration file: {{.*}}Inputs{{.}}config-l.cfg +! CHECK-LINKING: "-ffast-math" +! CHECK-LINKING: "--as-needed" "{{.*}}-{{.*}}.o" "-lmylib" "foo.a" "-lm" "-Bstatic" "-lhappy" "-Bdynamic" +! CHECK-LINKING-LIBOMP-GOES-AFTER: Configuration file: {{.*}}Inputs{{.}}config-l.cfg +! CHECK-LINKING-LIBOMP-GOES-AFTER: "-ffast-math" {{.*}}"-fopenmp" +! CHECK-LINKING-LIBOMP-GOES-AFTER: "--as-needed" "{{.*}}-{{.*}}.o" "-lmylib" "foo.a" "-lm" "-Bstatic" "-lhappy" "-Bdynamic" {{.*}}"-lomp" +! CHECK-NOLINKING: Configuration file: {{.*}}Inputs{{.}}config-l.cfg +! CHECK-NOLINKING: "-ffast-math" +! CHECK-NOLINKING-NO: "-lm" "-Bstatic" "-lhappy" "-Bdynamic" +! CHECK-NOLINKING-OPENMP: Configuration file: {{.*}}Inputs{{.}}config-l.cfg +! CHECK-NOLINKING-OPENMP: "-ffast-math" {{.*}}"-fopenmp" +! CHECK-NOLINKING-OPENMP-NO: "-lm" "-Bstatic" "-lhappy" "-Bdynamic" {{.}}"-lomp" +! CHECK-LINKING-MSVC: Configuration file: {{.*}}Inputs{{.}}config-l.cfg +! CHECK-LINKING-MSVC: "-ffast-math" +! CHECK-LINKING-MSVC: "--as-needed" "{{.*}}-{{.*}}.o" "mylib.lib" "foo.lib" "m.lib" "-Bstatic" "happy.lib" "-Bdynamic" +! CHECK-NOLINKING-MSVC: Configuration file: {{.*}}Inputs{{.}}config-l.cfg +! CHECK-NOLINKING-MSVC: "-ffast-math" +! CHECK-NOLINKING-MSVC-NO: "m.lib" "-Bstatic" "happy.lib" "-Bdynamic" diff --git a/flang/test/Driver/frontend-forwarding.f90 b/flang/test/Driver/frontend-forwarding.f90 index 382c1aa5d350b..ac232672b57a3 100644 --- a/flang/test/Driver/frontend-forwarding.f90 +++ b/flang/test/Driver/frontend-forwarding.f90 @@ -20,7 +20,6 @@ ! RUN: -fversion-loops-for-stride \ ! RUN: -flang-experimental-hlfir \ ! RUN: -flang-deprecated-no-hlfir \ -! RUN: -flang-experimental-integer-overflow \ ! RUN: -fno-ppc-native-vector-element-order \ ! RUN: -fppc-native-vector-element-order \ ! RUN: -mllvm -print-before-all \ @@ -52,7 +51,6 @@ ! CHECK: "-fversion-loops-for-stride" ! CHECK: "-flang-experimental-hlfir" ! CHECK: "-flang-deprecated-no-hlfir" -! CHECK: "-flang-experimental-integer-overflow" ! CHECK: "-fno-ppc-native-vector-element-order" ! CHECK: "-fppc-native-vector-element-order" ! CHECK: "-Rpass" diff --git a/flang/test/Driver/fveclib.f90 b/flang/test/Driver/fveclib.f90 index 14c59b0616f82..490ce974724a6 100644 --- a/flang/test/Driver/fveclib.f90 +++ b/flang/test/Driver/fveclib.f90 @@ -30,3 +30,20 @@ ! TODO: if we add support for -nostdlib or -nodefaultlibs we need to test that ! these prevent "-framework Accelerate" being added on Darwin + +! RUN: %flang -### --target=aarch64-pc-windows-msvc -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-MSVC %s +! RUN: %flang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-LINUX %s +! RUN: %flang -### --target=aarch64-linux-gnu -fveclib=ArmPL %s -lamath 2>&1 | FileCheck --check-prefix=CHECK-LINKING-AMATH-BEFORE-ARMPL-LINUX %s +! RUN: %flang -### --target=arm64-apple-darwin -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-LINKING-ARMPL-DARWIN %s +! RUN: %flang -### --target=arm64-apple-darwin -fveclib=ArmPL %s -lamath 2>&1 | FileCheck --check-prefix=CHECK-LINKING-AMATH-BEFORE-ARMPL-DARWIN %s +! CHECK-LINKING-ARMPL-LINUX: "--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state" +! CHECK-LINKING-ARMPL-DARWIN: "-lm" "-lamath" "-lm" +! CHECK-LINKING-ARMPL-MSVC: "--dependent-lib=amath" +! CHECK-LINKING-AMATH-BEFORE-ARMPL-LINUX: "-lamath" {{.*}}"--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state" +! CHECK-LINKING-AMATH-BEFORE-ARMPL-DARWIN: "-lamath" {{.*}}"-lm" "-lamath" "-lm" + +! RUN: %flang -### --target=aarch64-linux-gnu -resource-dir=%S/../../../clang/test/Driver/Inputs/resource_dir_with_arch_subdir -frtlib-add-rpath -fveclib=ArmPL %s 2>&1 | FileCheck --check-prefix=CHECK-RPATH-ARMPL %s +! CHECK-RPATH-ARMPL: "--push-state" "--as-needed" "-lm" "-lamath" "-lm" "--pop-state" +! We need to see "-rpath" at least twice, one for veclib, one for the Fortran runtime +! CHECK-RPATH-ARMPL-SAME: "-rpath" +! CHECK-RPATH-ARMPL-SAME: "-rpath" diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90 index 4326953421e4b..edc6f59b0ad7c 100644 --- a/flang/test/Driver/mlir-debug-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90 @@ -28,13 +28,11 @@ ! ALL: Pass statistics report ! ALL: Fortran::lower::VerifierPass -! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] ! ALL-NEXT: 'fir.global' Pipeline ! ALL-NEXT: InlineElementals ! ALL-NEXT: 'func.func' Pipeline ! ALL-NEXT: InlineElementals -! ALL-NEXT: 'gpu.module' Pipeline -! ALL-NEXT: InlineElementals ! ALL-NEXT: 'omp.declare_reduction' Pipeline ! ALL-NEXT: InlineElementals ! ALL-NEXT: 'omp.private' Pipeline @@ -51,14 +49,12 @@ ! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd ! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd -! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] ! ALL-NEXT: 'fir.global' Pipeline ! ALL-NEXT: CharacterConversion ! ALL-NEXT: 'func.func' Pipeline ! ALL-NEXT: ArrayValueCopy ! ALL-NEXT: CharacterConversion -! ALL-NEXT: 'gpu.module' Pipeline -! ALL-NEXT: CharacterConversion ! ALL-NEXT: 'omp.declare_reduction' Pipeline ! ALL-NEXT: CharacterConversion ! ALL-NEXT: 'omp.private' Pipeline @@ -82,16 +78,13 @@ ! ALL-NEXT: PolymorphicOpConversion ! ALL-NEXT: AssumedRankOpConversion -! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] ! ALL-NEXT: 'fir.global' Pipeline ! ALL-NEXT: StackReclaim ! ALL-NEXT: CFGConversion ! ALL-NEXT: 'func.func' Pipeline ! ALL-NEXT: StackReclaim ! ALL-NEXT: CFGConversion -! ALL-NEXT: 'gpu.module' Pipeline -! ALL-NEXT: StackReclaim -! ALL-NEXT: CFGConversion ! ALL-NEXT: 'omp.declare_reduction' Pipeline ! ALL-NEXT: StackReclaim ! ALL-NEXT: CFGConversion @@ -112,7 +105,11 @@ ! ALL-NEXT: 'func.func' Pipeline ! ALL-NEXT: AbstractResultOpt ! ALL-NEXT: 'gpu.module' Pipeline -! ALL-NEXT: AbstractResultOpt +! ALL-NEXT: Pipeline Collection : ['func.func', 'gpu.func'] +! ALL-NEXT: 'func.func' Pipeline +! ALL-NEXT: AbstractResultOpt +! ALL-NEXT: 'gpu.func' Pipeline +! ALL-NEXT: AbstractResultOpt ! ALL-NEXT: 'omp.declare_reduction' Pipeline ! ALL-NEXT: AbstractResultOpt ! ALL-NEXT: 'omp.private' Pipeline diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90 index 6ffdbb0234e85..b30affe691b84 100644 --- a/flang/test/Driver/mlir-pass-pipeline.f90 +++ b/flang/test/Driver/mlir-pass-pipeline.f90 @@ -16,16 +16,13 @@ ! ALL: Fortran::lower::VerifierPass ! O2-NEXT: Canonicalizer -! ALL: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +! ALL: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] ! ALL-NEXT:'fir.global' Pipeline ! O2-NEXT: SimplifyHLFIRIntrinsics ! ALL: InlineElementals ! ALL-NEXT:'func.func' Pipeline ! O2-NEXT: SimplifyHLFIRIntrinsics ! ALL: InlineElementals -! ALL-NEXT:'gpu.module' Pipeline -! O2-NEXT: SimplifyHLFIRIntrinsics -! ALL: InlineElementals ! ALL-NEXT:'omp.declare_reduction' Pipeline ! O2-NEXT: SimplifyHLFIRIntrinsics ! ALL: InlineElementals @@ -36,13 +33,11 @@ ! O2-NEXT: CSE ! O2-NEXT: (S) {{.*}} num-cse'd ! O2-NEXT: (S) {{.*}} num-dce'd -! O2-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +! O2-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] ! O2-NEXT: 'fir.global' Pipeline ! O2-NEXT: OptimizedBufferization ! O2-NEXT: 'func.func' Pipeline ! O2-NEXT: OptimizedBufferization -! O2-NEXT: 'gpu.module' Pipeline -! O2-NEXT: OptimizedBufferization ! O2-NEXT: 'omp.declare_reduction' Pipeline ! O2-NEXT: OptimizedBufferization ! O2-NEXT: 'omp.private' Pipeline @@ -59,14 +54,12 @@ ! ALL-NEXT: (S) 0 num-cse'd - Number of operations CSE'd ! ALL-NEXT: (S) 0 num-dce'd - Number of operations DCE'd -! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] ! ALL-NEXT: 'fir.global' Pipeline ! ALL-NEXT: CharacterConversion ! ALL-NEXT: 'func.func' Pipeline ! ALL-NEXT: ArrayValueCopy ! ALL-NEXT: CharacterConversion -! ALL-NEXT: 'gpu.module' Pipeline -! ALL-NEXT: CharacterConversion ! ALL-NEXT: 'omp.declare_reduction' Pipeline ! ALL-NEXT: CharacterConversion ! ALL-NEXT: 'omp.private' Pipeline @@ -93,16 +86,13 @@ ! ALL-NEXT: AssumedRankOpConversion ! O2-NEXT: AddAliasTags -! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] ! ALL-NEXT: 'fir.global' Pipeline ! ALL-NEXT: StackReclaim ! ALL-NEXT: CFGConversion ! ALL-NEXT: 'func.func' Pipeline ! ALL-NEXT: StackReclaim ! ALL-NEXT: CFGConversion -! ALL-NEXT: 'gpu.module' Pipeline -! ALL-NEXT: StackReclaim -! ALL-NEXT: CFGConversion ! ALL-NEXT: 'omp.declare_reduction' Pipeline ! ALL-NEXT: StackReclaim ! ALL-NEXT: CFGConversion @@ -124,7 +114,11 @@ ! ALL-NEXT: 'func.func' Pipeline ! ALL-NEXT: AbstractResultOpt ! ALL-NEXT: 'gpu.module' Pipeline -! ALL-NEXT: AbstractResultOpt +! ALL-NEXT: Pipeline Collection : ['func.func', 'gpu.func'] +! ALL-NEXT: 'func.func' Pipeline +! ALL-NEXT: AbstractResultOpt +! ALL-NEXT: 'gpu.func' Pipeline +! ALL-NEXT: AbstractResultOpt ! ALL-NEXT: 'omp.declare_reduction' Pipeline ! ALL-NEXT: AbstractResultOpt ! ALL-NEXT: 'omp.private' Pipeline diff --git a/flang/test/Driver/options-loongarch.f90 b/flang/test/Driver/options-loongarch.f90 new file mode 100644 index 0000000000000..717bf6385b06d --- /dev/null +++ b/flang/test/Driver/options-loongarch.f90 @@ -0,0 +1,43 @@ +!! This test tests options from clang, which are also supported by flang in LoongArch. + +! RUN: %flang -c --target=loongarch64-unknown-linux -mlsx %s -### 2>&1 | FileCheck --check-prefixes=LSX,NOLASX %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mno-lsx %s -### 2>&1 | FileCheck --check-prefixes=NOLSX,NOLASX %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mlasx %s -### 2>&1 | FileCheck --check-prefixes=LSX,LASX %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mno-lasx %s -### 2>&1 | FileCheck --check-prefixes=LSX,NOLASX %s +! RUN: %flang -c --target=loongarch64-unknown-linux -msimd=none %s -### 2>&1 | FileCheck --check-prefixes=NOLSX,NOLASX %s +! RUN: %flang -c --target=loongarch64-unknown-linux -msimd=lsx %s -### 2>&1 | FileCheck --check-prefixes=LSX,NOLASX %s +! RUN: %flang -c --target=loongarch64-unknown-linux -msimd=lasx %s -### 2>&1 | FileCheck --check-prefixes=LSX,LASX %s +! RUN: not %flang -c --target=loongarch64-unknown-linux -msimd=supper %s -### 2>&1 | FileCheck --check-prefix=MSIMD-INVALID %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mfrecipe %s -### 2>&1 | FileCheck --check-prefix=FRECIPE %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mno-frecipe %s -### 2>&1 | FileCheck --check-prefix=NOFRECIPE %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mlam-bh %s -### 2>&1 | FileCheck --check-prefix=LAMBH %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mno-lam-bh %s -### 2>&1 | FileCheck --check-prefix=NOLAMBH %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mlamcas %s -### 2>&1 | FileCheck --check-prefix=LAMCAS %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mno-lamcas %s -### 2>&1 | FileCheck --check-prefix=NOLAMCAS %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mld-seq-sa %s -### 2>&1 | FileCheck --check-prefix=LD-SEQ-SA %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mno-ld-seq-sa %s -### 2>&1 | FileCheck --check-prefix=NOLD-SEQ-SA %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mdiv32 %s -### 2>&1 | FileCheck --check-prefix=DIV32 %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mno-div32 %s -### 2>&1 | FileCheck --check-prefix=NODIV32 %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mannotate-tablejump %s -### 2>&1 | FileCheck --check-prefix=ANOTATE %s +! RUN: %flang -c --target=loongarch64-unknown-linux -mno-annotate-tablejump %s -### 2>&1 | FileCheck --check-prefix=NOANOTATE %s + +! MSIMD-INVALID: error: invalid argument 'supper' to -msimd=; must be one of: none, lsx, lasx +! FRECIPE: "-target-feature" "+frecipe" +! NOFRECIPE-NOT: "-target-feature" "+frecipe" +! LAMBH: "-target-feature" "+lam-bh" +! NOLAMBH-NOT: "-target-feature" "+lam-bh" +! LAMCAS: "-target-feature" "+lamcas" +! NOLAMCAS-NOT: "-target-feature" "+lamcas" +! LD-SEQ-SA: "-target-feature" "+ld-seq-sa" +! NOLD-SEQ-SA-NOT: "-target-feature" "+ld-seq-sa" +! DIV32: "-target-feature" "+div32" +! NODIV32-NOT: "-target-feature" "+div32" +! ANOTATE: "-mllvm" "-loongarch-annotate-tablejump" +! NOANOTATE-NOT: "-loongarch-annotate-tablejump" + +! NOLSX-NOT: "-target-feature" "+lsx" +! NOLASX-NOT: "-target-feature" "+lasx" +! LSX-DAG: "-target-feature" "+lsx" +! LASX-DAG: "-target-feature" "+lasx" +! NOLSX-NOT: "-target-feature" "+lsx" +! NOLASX-NOT: "-target-feature" "+lasx" diff --git a/flang/test/Examples/omp-declarative-directive.f90 b/flang/test/Examples/omp-declarative-directive.f90 index 632ebcec17885..4a9ad9142bb18 100644 --- a/flang/test/Examples/omp-declarative-directive.f90 +++ b/flang/test/Examples/omp-declarative-directive.f90 @@ -7,7 +7,7 @@ ! 2.8.2 declare-simd subroutine declare_simd_1(a, b) - real(8), intent(inout) :: a, b + real(8), intent(inout), allocatable :: a, b !$omp declare simd(declare_simd_1) aligned(a) a = 3.14 + b end subroutine declare_simd_1 diff --git a/flang/test/Fir/CUDA/cuda-abstract-result.mlir b/flang/test/Fir/CUDA/cuda-abstract-result.mlir new file mode 100644 index 0000000000000..8c59487ca5cd5 --- /dev/null +++ b/flang/test/Fir/CUDA/cuda-abstract-result.mlir @@ -0,0 +1,37 @@ +// RUN: fir-opt -pass-pipeline='builtin.module(gpu.module(gpu.func(abstract-result)))' %s | FileCheck %s + +gpu.module @test { + gpu.func @_QMinterval_mPtest1(%arg0: !fir.ref>, %arg1: !fir.ref) -> !fir.type<_QMinterval_mTinterval{inf:f32,sup:f32}> { + %c1_i32 = arith.constant 1 : i32 + %18 = fir.dummy_scope : !fir.dscope + %19 = fir.declare %arg0 dummy_scope %18 {uniq_name = "_QMinterval_mFtest1Ea"} : (!fir.ref>, !fir.dscope) -> !fir.ref> + %20 = fir.declare %arg1 dummy_scope %18 {uniq_name = "_QMinterval_mFtest1Eb"} : (!fir.ref, !fir.dscope) -> !fir.ref + %21 = fir.alloca !fir.type<_QMinterval_mTinterval{inf:f32,sup:f32}> {bindc_name = "c", uniq_name = "_QMinterval_mFtest1Ec"} + %22 = fir.declare %21 {uniq_name = "_QMinterval_mFtest1Ec"} : (!fir.ref>) -> !fir.ref> + %23 = fir.alloca i32 {bindc_name = "warpsize", uniq_name = "_QMcudadeviceECwarpsize"} + %24 = fir.declare %23 {uniq_name = "_QMcudadeviceECwarpsize"} : (!fir.ref) -> !fir.ref + %25 = fir.field_index inf, !fir.type<_QMinterval_mTinterval{inf:f32,sup:f32}> + %26 = fir.coordinate_of %19, %25 : (!fir.ref>, !fir.field) -> !fir.ref + %27 = fir.load %20 : !fir.ref + %28 = arith.negf %27 fastmath : f32 + %29 = fir.load %26 : !fir.ref + %30 = fir.call @__fadd_rd(%29, %28) proc_attrs fastmath : (f32, f32) -> f32 + %31 = fir.field_index inf, !fir.type<_QMinterval_mTinterval{inf:f32,sup:f32}> + %32 = fir.coordinate_of %22, %31 : (!fir.ref>, !fir.field) -> !fir.ref + fir.store %30 to %32 : !fir.ref + %33 = fir.field_index sup, !fir.type<_QMinterval_mTinterval{inf:f32,sup:f32}> + %34 = fir.coordinate_of %19, %33 : (!fir.ref>, !fir.field) -> !fir.ref + %35 = fir.load %20 : !fir.ref + %36 = arith.negf %35 fastmath : f32 + %37 = fir.load %34 : !fir.ref + %38 = fir.call @__fadd_ru(%37, %36) proc_attrs fastmath : (f32, f32) -> f32 + %39 = fir.field_index sup, !fir.type<_QMinterval_mTinterval{inf:f32,sup:f32}> + %40 = fir.coordinate_of %22, %39 : (!fir.ref>, !fir.field) -> !fir.ref + fir.store %38 to %40 : !fir.ref + %41 = fir.load %22 : !fir.ref> + gpu.return %41 : !fir.type<_QMinterval_mTinterval{inf:f32,sup:f32}> + } +} + +// CHECK: gpu.func @_QMinterval_mPtest1(%arg0: !fir.ref>, %arg1: !fir.ref>, %arg2: !fir.ref) { +// CHECK: gpu.return{{$}} diff --git a/flang/test/Fir/CUDA/cuda-code-gen.mlir b/flang/test/Fir/CUDA/cuda-code-gen.mlir new file mode 100644 index 0000000000000..55e473ef2549e --- /dev/null +++ b/flang/test/Fir/CUDA/cuda-code-gen.mlir @@ -0,0 +1,29 @@ +// RUN: fir-opt --split-input-file --fir-to-llvm-ir="target=x86_64-unknown-linux-gnu" %s | FileCheck %s + +module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry, dense<64> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<4xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>} { + + func.func @_QQmain() attributes {fir.bindc_name = "cufkernel_global"} { + %c0 = arith.constant 0 : index + %0 = fir.address_of(@_QQclX3C737464696E3E00) : !fir.ref> + %c4_i32 = arith.constant 4 : i32 + %c48 = arith.constant 48 : index + %1 = fir.convert %c48 : (index) -> i64 + %2 = fir.convert %0 : (!fir.ref>) -> !fir.ref + %3 = fir.call @_FortranACUFAllocDesciptor(%1, %2, %c4_i32) : (i64, !fir.ref, i32) -> !fir.ref> + %4 = fir.convert %3 : (!fir.ref>) -> !fir.ref>>> + %5 = fir.zero_bits !fir.heap> + %6 = fircg.ext_embox %5(%c0) {allocator_idx = 2 : i32} : (!fir.heap>, index) -> !fir.box>> + fir.store %6 to %4 : !fir.ref>>> + %8 = fir.load %3 : !fir.ref> + return + } + + // CHECK-LABEL: llvm.func @_QQmain() + // CHECK-COUNT-2: llvm.call @_FortranACUFAllocDesciptor + + fir.global linkonce @_QQclX3C737464696E3E00 constant : !fir.char<1,8> { + %0 = fir.string_lit "\00"(8) : !fir.char<1,8> + fir.has_value %0 : !fir.char<1,8> + } + func.func private @_FortranACUFAllocDesciptor(i64, !fir.ref, i32) -> !fir.ref> attributes {fir.runtime} +} diff --git a/flang/test/Fir/CUDA/cuda-constructor-2.f90 b/flang/test/Fir/CUDA/cuda-constructor-2.f90 index 29efdb083878a..eb118ccee311c 100644 --- a/flang/test/Fir/CUDA/cuda-constructor-2.f90 +++ b/flang/test/Fir/CUDA/cuda-constructor-2.f90 @@ -39,7 +39,7 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, f80 = dense<128> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, i64 = dense<64> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, f128 = dense<128> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.endianness" = "little">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", gpu.container_module, llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 20.0.0 (https://github.com/llvm/llvm-project.git 3372303188df0f7f8ac26e7ab610cf8b0f716d42)", llvm.target_triple = "x86_64-unknown-linux-gnu"} { - fir.global @_QMiso_c_bindingECc_int {data_attr = #cuf.cuda} constant : i32 + fir.global @_QMiso_c_bindingECc_int constant : i32 fir.type_info @_QM__fortran_builtinsT__builtin_c_ptr noinit nodestroy nofinal : !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}> diff --git a/flang/test/Fir/CUDA/cuda-external-mangling.mlir b/flang/test/Fir/CUDA/cuda-external-mangling.mlir new file mode 100644 index 0000000000000..cd028a201e6fa --- /dev/null +++ b/flang/test/Fir/CUDA/cuda-external-mangling.mlir @@ -0,0 +1,25 @@ +// RUN: fir-opt --split-input-file --external-name-interop %s | FileCheck %s + +module @mod attributes {gpu.container_module} { + +gpu.module @cuda_device_mod { + gpu.func @_QPfoo() kernel { + fir.call @_QPthreadfence() fastmath : () -> () + gpu.return + } + func.func private @_QPthreadfence() attributes {cuf.proc_attr = #cuf.cuda_proc} +} + +func.func @test() -> () { + %0 = llvm.mlir.constant(0 : i64) : i64 + %1 = llvm.mlir.constant(0 : i32) : i32 + gpu.launch_func @cuda_device_mod::@_QPfoo blocks in (%0, %0, %0) threads in (%0, %0, %0) : i64 dynamic_shared_memory_size %1 + return +} + +// CHECK-LABEL: gpu.func @foo_() +// CHECK: fir.call @threadfence_() +// CHECK: func.func private @threadfence_() +// CHECK: gpu.launch_func @cuda_device_mod::@foo_ + +} diff --git a/flang/test/Fir/CUDA/cuda-extranal-mangling.mlir b/flang/test/Fir/CUDA/cuda-extranal-mangling.mlir deleted file mode 100644 index 551a89a7018c2..0000000000000 --- a/flang/test/Fir/CUDA/cuda-extranal-mangling.mlir +++ /dev/null @@ -1,13 +0,0 @@ -// RUN: fir-opt --split-input-file --external-name-interop %s | FileCheck %s - -gpu.module @cuda_device_mod { - gpu.func @_QPfoo() { - fir.call @_QPthreadfence() fastmath : () -> () - gpu.return - } - func.func private @_QPthreadfence() attributes {cuf.proc_attr = #cuf.cuda_proc} -} - -// CHECK-LABEL: gpu.func @_QPfoo -// CHECK: fir.call @threadfence_() -// CHECK: func.func private @threadfence_() diff --git a/flang/test/Fir/CUDA/cuda-global-addr.mlir b/flang/test/Fir/CUDA/cuda-global-addr.mlir index 2baead4010f5c..94ee74736f650 100644 --- a/flang/test/Fir/CUDA/cuda-global-addr.mlir +++ b/flang/test/Fir/CUDA/cuda-global-addr.mlir @@ -1,4 +1,4 @@ -// RUN: fir-opt --cuf-convert %s | FileCheck %s +// RUN: fir-opt --split-input-file --cuf-convert %s | FileCheck %s module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry, dense<64> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<4xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>} { fir.global @_QMmod1Eadev {data_attr = #cuf.cuda} : !fir.array<10xi32> { @@ -34,3 +34,33 @@ func.func @_QQmain() attributes {fir.bindc_name = "test"} { // CHECK: %[[ARRAY_COOR:.*]] = fir.array_coor %[[DECL]](%{{.*}}) %c4{{.*}} : (!fir.ref>, !fir.shape<1>, index) -> !fir.ref // CHECK: %[[ARRAY_COOR_PTR:.*]] = fir.convert %[[ARRAY_COOR]] : (!fir.ref) -> !fir.llvm_ptr // CHECK: fir.call @_FortranACUFDataTransferPtrPtr(%[[ARRAY_COOR_PTR]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) : (!fir.llvm_ptr, !fir.llvm_ptr, i64, i32, !fir.ref, i32) -> none + +// ----- + +module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry, dense<64> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<4xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>} { + + fir.global @_QMdevmodEdarray {data_attr = #cuf.cuda} : !fir.box>> { + %c0 = arith.constant 0 : index + %0 = fir.zero_bits !fir.heap> + %1 = fir.shape %c0 : (index) -> !fir.shape<1> + %2 = fir.embox %0(%1) {allocator_idx = 2 : i32} : (!fir.heap>, !fir.shape<1>) -> !fir.box>> + fir.has_value %2 : !fir.box>> + } + func.func @_QQmain() attributes {fir.bindc_name = "arraysize"} { + %0 = fir.address_of(@_QMiso_c_bindingECc_int) : !fir.ref + %1 = fir.declare %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QMiso_c_bindingECc_int"} : (!fir.ref) -> !fir.ref + %2 = fir.address_of(@_QMdevmodEdarray) : !fir.ref>>> + %3 = fir.declare %2 {data_attr = #cuf.cuda, fortran_attrs = #fir.var_attrs, uniq_name = "_QMdevmodEdarray"} : (!fir.ref>>>) -> !fir.ref>>> + %4 = fir.alloca i32 {bindc_name = "exp", uniq_name = "_QFEexp"} + %5 = fir.declare %4 {uniq_name = "_QFEexp"} : (!fir.ref) -> !fir.ref + %6 = fir.alloca i32 {bindc_name = "hsize", uniq_name = "_QFEhsize"} + %7 = fir.declare %6 {uniq_name = "_QFEhsize"} : (!fir.ref) -> !fir.ref + return + } + fir.global @_QMiso_c_bindingECc_int constant : i32 +} + +// We cannot call _FortranACUFGetDeviceAddress on a constant global. +// There is no symbol for it and the call would result into an unresolved reference. +// CHECK-NOT: fir.call {{.*}}GetDeviceAddress + diff --git a/flang/test/Fir/CUDA/cuda-gpu-launch-func.mlir b/flang/test/Fir/CUDA/cuda-gpu-launch-func.mlir index 7fede7c6c17b7..3db2336c90a7d 100644 --- a/flang/test/Fir/CUDA/cuda-gpu-launch-func.mlir +++ b/flang/test/Fir/CUDA/cuda-gpu-launch-func.mlir @@ -99,9 +99,16 @@ module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : ve } // CHECK-LABEL: _QMmod1Phost_sub - +// CHECK: %[[STRUCT:.*]] = llvm.alloca %{{.*}} x !llvm.struct<(ptr)> : (i32) -> !llvm.ptr +// CHECK: %[[PARAMS:.*]] = llvm.alloca %{{.*}} x !llvm.ptr : (i32) -> !llvm.ptr +// CHECK: %[[ZERO:.*]] = llvm.mlir.constant(0 : i32) : i32 +// CHECK: %[[STRUCT_PTR:.*]] = llvm.getelementptr %[[STRUCT]][%{{.*}}, {{.*}}] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.struct<(ptr)> +// CHECK: llvm.store %{{.*}}, %[[STRUCT_PTR]] : !llvm.ptr, !llvm.ptr +// CHECK: %[[PARAM_PTR:.*]] = llvm.getelementptr %[[PARAMS]][%[[ZERO]]] : (!llvm.ptr, i32) -> !llvm.ptr, !llvm.ptr +// CHECK: llvm.store %[[STRUCT_PTR]], %[[PARAM_PTR]] : !llvm.ptr, !llvm.ptr // CHECK: %[[KERNEL_PTR:.*]] = llvm.mlir.addressof @_QMmod1Psub1 : !llvm.ptr -// CHECK: llvm.call @_FortranACUFLaunchKernel(%[[KERNEL_PTR]], {{.*}}) +// CHECK: %[[NULL:.*]] = llvm.mlir.zero : !llvm.ptr +// CHECK: llvm.call @_FortranACUFLaunchKernel(%[[KERNEL_PTR]], {{.*}}, %[[PARAMS]], %[[NULL]]) // ----- diff --git a/flang/test/Fir/CUDA/cuda-implicit-device-global.f90 b/flang/test/Fir/CUDA/cuda-implicit-device-global.f90 index 772e2696171a6..9b22ed86e419c 100644 --- a/flang/test/Fir/CUDA/cuda-implicit-device-global.f90 +++ b/flang/test/Fir/CUDA/cuda-implicit-device-global.f90 @@ -23,7 +23,7 @@ // Test that global used in device function are flagged with the correct // CHECK: %[[GLOBAL:.*]] = fir.address_of(@_QQcl[[SYMBOL:.*]]) : !fir.ref> // CHECK: %[[CONV:.*]] = fir.convert %[[GLOBAL]] : (!fir.ref>) -> !fir.ref // CHECK: fir.call @_FortranAioBeginExternalListOutput(%{{.*}}, %[[CONV]], %{{.*}}) fastmath : (i32, !fir.ref, i32) -> !fir.ref -// CHECK: fir.global linkonce @_QQcl[[SYMBOL]] {data_attr = #cuf.cuda} constant : !fir.char<1,32> +// CHECK: fir.global linkonce @_QQcl[[SYMBOL]] constant : !fir.char<1,32> // CHECK-LABEL: gpu.module @cuda_device_mod // CHECK: fir.global linkonce @_QQclX6995815537abaf90e86ce166af128f3a @@ -99,10 +99,11 @@ // Test that global used in device function are flagged with the correct fir.has_value %0 : !fir.char<1,11> } -// CHECK: fir.global linkonce @_QQclX5465737420504153534544 {data_attr = #cuf.cuda} constant : !fir.char<1,11> +// Checking that a constant fir.global that is only used in host code is not copied over to the device +// CHECK: fir.global linkonce @_QQclX5465737420504153534544 constant : !fir.char<1,11> // CHECK-LABEL: gpu.module @cuda_device_mod -// CHECK: fir.global linkonce @_QQclX5465737420504153534544 {data_attr = #cuf.cuda} constant +// CHECK-NOT: fir.global linkonce @_QQclX5465737420504153534544 // ----- @@ -140,7 +141,170 @@ // Test that global used in device function are flagged with the correct } func.func private @_FortranAioEndIoStatement(!fir.ref) -> i32 attributes {fir.io, fir.runtime} -// CHECK: fir.global linkonce @_QQclX5465737420504153534544 {data_attr = #cuf.cuda} constant : !fir.char<1,11> +// Checking that a constant fir.global that is used in device code is copied over to the device +// CHECK: fir.global linkonce @_QQclX5465737420504153534544 constant : !fir.char<1,11> // CHECK-LABEL: gpu.module @cuda_device_mod -// CHECK: fir.global linkonce @_QQclX5465737420504153534544 {data_attr = #cuf.cuda} constant +// CHECK: fir.global linkonce @_QQclX5465737420504153534544 constant + +// ----- + +func.func @_QQmain() attributes {fir.bindc_name = "cufkernel_global"} { + %c10 = arith.constant 10 : index + %c5_i32 = arith.constant 5 : i32 + %c6_i32 = arith.constant 6 : i32 + %c1 = arith.constant 1 : index + %c1_i32 = arith.constant 1 : i32 + %c10_i32 = arith.constant 10 : i32 + %0 = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"} + %1:2 = hlfir.declare %0 {uniq_name = "_QFEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) + cuf.kernel<<<%c10_i32, %c1_i32>>> (%arg0 : index) = (%c1 : index) to (%c10 : index) step (%c1 : index) { + %2 = fir.convert %arg0 : (index) -> i32 + fir.store %2 to %1#1 : !fir.ref + %3 = fir.load %1#0 : !fir.ref + %4 = arith.cmpi eq, %3, %c1_i32 : i32 + cf.cond_br %4, ^bb1, ^bb2 + ^bb1: // pred: ^bb0 + %5 = fir.address_of(@_QQclX91d13f6e74caa2f03965d7a7c6a8fdd5) : !fir.ref> + %6 = fir.convert %5 : (!fir.ref>) -> !fir.ref + %7 = fir.call @_FortranAioBeginExternalListOutput(%c6_i32, %6, %c5_i32) fastmath : (i32, !fir.ref, i32) -> !fir.ref + %8 = fir.load %1#0 : !fir.ref + %9 = fir.call @_FortranAioOutputInteger32(%7, %8) fastmath : (!fir.ref, i32) -> i1 + %10 = fir.call @_FortranAioEndIoStatement(%7) fastmath : (!fir.ref) -> i32 + cf.br ^bb2 + ^bb2: // 2 preds: ^bb0, ^bb1 + "fir.end"() : () -> () + } + return +} +func.func private @_FortranAioBeginExternalListOutput(i32, !fir.ref, i32) -> !fir.ref attributes {fir.io, fir.runtime} +fir.global linkonce @_QQclX91d13f6e74caa2f03965d7a7c6a8fdd5 constant : !fir.char<1,50> { + %0 = fir.string_lit "/local/home/vclement/llvm-project/build/dummy.cuf\00"(50) : !fir.char<1,50> + fir.has_value %0 : !fir.char<1,50> +} +func.func private @_FortranAioOutputInteger32(!fir.ref, i32) -> i1 attributes {fir.io, fir.runtime} +func.func private @_FortranAioEndIoStatement(!fir.ref) -> i32 attributes {fir.io, fir.runtime} +func.func private @_FortranAProgramStart(i32, !llvm.ptr, !llvm.ptr, !llvm.ptr) +func.func private @_FortranAProgramEndStatement() + +// CHECK-LABEL: func.func @_QQmain() +// CHECK: fir.global linkonce @_QQclX91d13f6e74caa2f03965d7a7c6a8fdd5 constant : !fir.char<1,50> +// CHECK: gpu.module @cuda_device_mod +// CHECK: fir.global linkonce @_QQclX91d13f6e74caa2f03965d7a7c6a8fdd5 constant : !fir.char<1,50> + +// ----- + +func.func @_QMmtestsPtestany() attributes {cuf.proc_attr = #cuf.cuda_proc} { + %1135 = fir.alloca !fir.type<_QM__mod1T__builtin_c_devptr{cptr:!fir.type<_QM__mod1T__builtin_c_ptr{__address:i64}>}> {bindc_name = "x", uniq_name = "_QMmtestsFtestanyEx"} + %1136 = fir.declare %1135 {uniq_name = "_QMmtestsFtestanyEx"} : (!fir.ref}>>) -> !fir.ref}>> + %1138 = fir.embox %1136 : (!fir.ref}>>) -> !fir.box}>> + return +} +fir.type_info @_QM__mod1T__builtin_c_devptr noinit nodestroy nofinal : !fir.type<_QM__mod1T__builtin_c_devptr{cptr:!fir.type<_QM__mod1T__builtin_c_ptr{__address:i64}>}> +fir.global linkonce_odr @_QM__mod1E.dt.__builtin_c_devptr constant : !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> { + %c1_i8 = arith.constant 1 : i8 + %c0_i8 = arith.constant 0 : i8 + %c0_i32 = arith.constant 0 : i32 + %c1 = arith.constant 1 : index + %c8_i64 = arith.constant 8 : i64 + %c18 = arith.constant 18 : index + %c0 = arith.constant 0 : index + %0 = fir.undefined !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %1 = fir.zero_bits !fir.ptr,name:!fir.box>>}>>> + %2 = fir.shape %c0 : (index) -> !fir.shape<1> + %3 = fir.embox %1(%2) : (!fir.ptr,name:!fir.box>>}>>>, !fir.shape<1>) -> !fir.box,name:!fir.box>>}>>>> + %4 = fir.insert_value %0, %3, ["binding", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, !fir.box,name:!fir.box>>}>>>>) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %5 = fir.address_of(@_QM__mod1E.n.__builtin_c_devptr) : !fir.ref> + %6 = fir.declare %5 typeparams %c18 {fortran_attrs = #fir.var_attrs, uniq_name = "_QM__mod1E.n.__builtin_c_devptr"} : (!fir.ref>, index) -> !fir.ref> + %7 = fir.embox %6 : (!fir.ref>) -> !fir.box> + %8 = fir.rebox %7 : (!fir.box>) -> !fir.box>> + %9 = fir.insert_value %4, %8, ["name", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, !fir.box>>) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %10 = fir.insert_value %9, %c8_i64, ["sizeinbytes", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, i64) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %11 = fir.zero_bits !fir.ptr,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>> + %12 = fir.embox %11 : (!fir.ptr,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>) -> !fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>> + %13 = fir.insert_value %10, %12, ["uninstantiated", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, !fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>>) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %14 = fir.zero_bits !fir.ptr> + %15 = fir.embox %14(%2) : (!fir.ptr>, !fir.shape<1>) -> !fir.box>> + %16 = fir.insert_value %13, %15, ["kindparameter", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, !fir.box>>) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %17 = fir.zero_bits !fir.ptr> + %18 = fir.embox %17(%2) : (!fir.ptr>, !fir.shape<1>) -> !fir.box>> + %19 = fir.insert_value %16, %18, ["lenparameterkind", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, !fir.box>>) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %20 = fir.address_of(@_QM__mod1E.c.__builtin_c_devptr) : !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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>>> + %21 = fir.shape_shift %c0, %c1 : (index, index) -> !fir.shapeshift<1> + %22 = fir.declare %20(%21) {fortran_attrs = #fir.var_attrs, uniq_name = "_QM__mod1E.c.__builtin_c_devptr"} : (!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>>>, !fir.shapeshift<1>) -> !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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>>> + %23 = fir.embox %22(%21) : (!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>>> + %24 = fir.shift %c0 : (index) -> !fir.shift<1> + %25 = fir.rebox %23(%24) : (!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>>>, !fir.shift<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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>>>> + %26 = fir.insert_value %19, %25, ["component", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, !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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>>>>) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %27 = fir.zero_bits !fir.ptr>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>> + %28 = fir.embox %27(%2) : (!fir.ptr>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>, !fir.shape<1>) -> !fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>> + %29 = fir.insert_value %26, %28, ["procptr", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, !fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %30 = fir.zero_bits !fir.ptr,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>> + %31 = fir.embox %30(%2) : (!fir.ptr,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>, !fir.shape<1>) -> !fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>> + %32 = fir.insert_value %29, %31, ["special", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, !fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %33 = fir.insert_value %32, %c0_i32, ["specialbitset", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, i32) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %34 = fir.insert_value %33, %c0_i8, ["hasparent", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, i8) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %35 = fir.insert_value %34, %c1_i8, ["noinitializationneeded", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, i8) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %36 = fir.insert_value %35, %c1_i8, ["nodestructionneeded", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, i8) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + %37 = fir.insert_value %36, %c1_i8, ["nofinalizationneeded", !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>] : (!fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>, i8) -> !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> + fir.has_value %37 : !fir.type<_QM__fortran_type_infoTderivedtype{binding:!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}> +} +fir.global linkonce_odr @_QM__mod1E.n.__builtin_c_devptr constant : !fir.char<1,18> { + %0 = fir.string_lit "__builtin_c_devptr"(18) : !fir.char<1,18> + fir.has_value %0 : !fir.char<1,18> +} +fir.global linkonce_odr @_QM__mod1E.c.__builtin_c_devptr constant : !fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>> { + %c0 = arith.constant 0 : index + %c0_i64 = arith.constant 0 : i64 + %c0_i8 = arith.constant 0 : i8 + %c5_i8 = arith.constant 5 : i8 + %c1_i8 = arith.constant 1 : i8 + %c4 = arith.constant 4 : index + %0 = fir.undefined !fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>> + %1 = fir.undefined !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}> + %2 = fir.address_of(@_QM__mod1E.n.cptr) : !fir.ref> + %3 = fir.declare %2 typeparams %c4 {fortran_attrs = #fir.var_attrs, uniq_name = "_QM__mod1E.n.cptr"} : (!fir.ref>, index) -> !fir.ref> + %4 = fir.embox %3 : (!fir.ref>) -> !fir.box> + %5 = fir.rebox %4 : (!fir.box>) -> !fir.box>> + %6 = fir.insert_value %1, %5, ["name", !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>] : (!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>, !fir.box>>) -> !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}> + %7 = fir.insert_value %6, %c1_i8, ["genre", !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>] : (!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>, i8) -> !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}> + %8 = fir.insert_value %7, %c5_i8, ["category", !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>] : (!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>, i8) -> !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}> + %9 = fir.insert_value %8, %c0_i8, ["kind", !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>] : (!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>, i8) -> !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}> + %10 = fir.insert_value %9, %c0_i8, ["rank", !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>] : (!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>, i8) -> !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}> + %11 = fir.insert_value %10, %c0_i64, ["offset", !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>] : (!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>, i64) -> !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}> + %12 = fir.undefined !fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}> + %13 = fir.insert_value %12, %c1_i8, ["genre", !fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>] : (!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>, i8) -> !fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}> + %14 = fir.insert_value %13, %c0_i64, ["value", !fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>] : (!fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>, i64) -> !fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}> + %15 = fir.insert_value %11, %14, ["characterlen", !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>] : (!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>, !fir.type<_QM__fortran_type_infoTvalue{genre:i8,__padding0:!fir.array<7xi8>,value:i64}>) -> !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}> + %16 = fir.address_of(@_QM__mod1E.dt.__builtin_c_ptr) : !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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>> + %17 = fir.declare %16 {fortran_attrs = #fir.var_attrs, uniq_name = "_QM__mod1E.dt.__builtin_c_ptr"} : (!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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>> + %18 = fir.embox %17 : (!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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>) -> !fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>> + %19 = fir.rebox %18 : (!fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>) -> !fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>> + %20 = fir.insert_value %15, %19, ["derived", !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>] : (!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>, !fir.box,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__mod1T__builtin_c_ptr{__address:i64}>}>>>>,procptr:!fir.box>>,offset:i64,initialization:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__builtin_c_funptr{__address:i64}>}>>>>,specialbitset:i32,hasparent:i8,noinitializationneeded:i8,nodestructionneeded:i8,nofinalizationneeded:i8,__padding0:!fir.array<4xi8>}>>>) -> !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}> + %21 = fir.zero_bits !fir.ptr,value:i64}>>> + %22 = fir.shape %c0 : (index) -> !fir.shape<1> + %23 = fir.embox %21(%22) : (!fir.ptr,value:i64}>>>, !fir.shape<1>) -> !fir.box,value:i64}>>>> + %24 = fir.insert_value %20, %23, ["lenvalue", !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>] : (!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>, !fir.box,value:i64}>>>>) -> !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}> + %25 = fir.zero_bits !fir.ptr,value:i64}>>> + %26 = fir.shape %c0, %c0 : (index, index) -> !fir.shape<2> + %27 = fir.embox %25(%26) : (!fir.ptr,value:i64}>>>, !fir.shape<2>) -> !fir.box,value:i64}>>>> + %28 = fir.insert_value %24, %27, ["bounds", !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>] : (!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>, !fir.box,value:i64}>>>>) -> !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}> + %29 = fir.zero_bits !fir.ref + %30 = fir.convert %29 : (!fir.ref) -> i64 + %31 = fir.undefined !fir.type<_QM__mod1T__builtin_c_ptr{__address:i64}> + %32 = fir.insert_value %31, %30, ["__address", !fir.type<_QM__mod1T__builtin_c_ptr{__address:i64}>] : (!fir.type<_QM__mod1T__builtin_c_ptr{__address:i64}>, i64) -> !fir.type<_QM__mod1T__builtin_c_ptr{__address:i64}> + %33 = fir.insert_value %28, %32, ["initialization", !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>] : (!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>, !fir.type<_QM__mod1T__builtin_c_ptr{__address:i64}>) -> !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}> + %34 = fir.insert_value %0, %33, [0 : index] : (!fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>>, !fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>) -> !fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>> + fir.has_value %34 : !fir.array<1x!fir.type<_QM__fortran_type_infoTcomponent{name:!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__mod1T__builtin_c_funptr{__address:i64}>}>>>>,special:!fir.box,proc:!fir.type<_QM__mod1T__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__mod1T__builtin_c_ptr{__address:i64}>}>> +} +fir.global linkonce_odr @_QM__mod1E.n.cptr constant : !fir.char<1,4> { + %0 = fir.string_lit "cptr"(4) : !fir.char<1,4> + fir.has_value %0 : !fir.char<1,4> +} + +// CHECK-LABEL: func.func @_QMmtestsPtestany() +// CHECK: gpu.module @cuda_device_mod +// CHECK-DAG: fir.global linkonce_odr @_QM__mod1E.n.cptr +// CHECK-DAG: fir.global linkonce_odr @_QM__mod1E.c.__builtin_c_devptr +// CHECK-DAG: fir.global linkonce_odr @_QM__mod1E.dt.__builtin_c_devptr +// CHECK-DAG: fir.global linkonce_odr @_QM__mod1E.n.__builtin_c_devptr diff --git a/flang/test/Fir/CUDA/cuda-target-rewrite.mlir b/flang/test/Fir/CUDA/cuda-target-rewrite.mlir index c14efc8b13f66..0e7534e06c89c 100644 --- a/flang/test/Fir/CUDA/cuda-target-rewrite.mlir +++ b/flang/test/Fir/CUDA/cuda-target-rewrite.mlir @@ -1,5 +1,5 @@ // REQUIRES: x86-registered-target -// RUN: fir-opt --target-rewrite="target=x86_64-unknown-linux-gnu" %s | FileCheck %s +// RUN: fir-opt --split-input-file --target-rewrite="target=x86_64-unknown-linux-gnu" %s | FileCheck %s gpu.module @testmod { gpu.func @_QPvcpowdk(%arg0: !fir.ref> {cuf.data_attr = #cuf.cuda, fir.bindc_name = "a"}) attributes {cuf.proc_attr = #cuf.cuda_proc} { @@ -15,3 +15,39 @@ gpu.module @testmod { // CHECK-LABEL: gpu.func @_QPvcpowdk // CHECK: %{{.*}} = fir.call @_FortranAzpowk(%{{.*}}, %{{.*}}, %{{.*}}) : (f64, f64, i64) -> tuple // CHECK: func.func private @_FortranAzpowk(f64, f64, i64) -> tuple attributes {fir.bindc_name = "_FortranAzpowk", fir.runtime} + +// ----- + +gpu.module @testmod { + gpu.func @_QPtest(%arg0: complex) -> (complex) { + gpu.return %arg0 : complex + } +} + +// CHECK-LABEL: gpu.func @_QPtest +// CHECK-SAME: (%arg0: f64, %arg1: f64) -> tuple { +// CHECK: gpu.return %{{.*}} : tuple + + +// ----- +module attributes {gpu.container_module} { + +gpu.module @testmod { + gpu.func @_QPtest(%arg0: complex) -> () kernel { + gpu.return + } +} + +func.func @main(%arg0: complex) { + %0 = llvm.mlir.constant(0 : i64) : i64 + %1 = llvm.mlir.constant(0 : i32) : i32 + gpu.launch_func @testmod::@_QPtest blocks in (%0, %0, %0) threads in (%0, %0, %0) : i64 dynamic_shared_memory_size %1 args(%arg0 : complex) + return +} + +} + +// CHECK-LABEL: gpu.func @_QPtest +// CHECK-SAME: (%arg0: f64, %arg1: f64) kernel { +// CHECK: gpu.return +// CHECK: gpu.launch_func @testmod::@_QPtest blocks in (%{{.*}}, %{{.*}}, %{{.*}}) threads in (%{{.*}}, %{{.*}}, %{{.*}}) : i64 dynamic_shared_memory_size %{{.*}} args(%{{.*}} : f64, %{{.*}} : f64) diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir index 50b91ce340b3a..d2788008c3893 100644 --- a/flang/test/Fir/basic-program.fir +++ b/flang/test/Fir/basic-program.fir @@ -17,16 +17,13 @@ func.func @_QQmain() { // PASSES: Pass statistics report // PASSES: Canonicalizer -// PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +// PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] // PASSES-NEXT: 'fir.global' Pipeline // PASSES-NEXT: SimplifyHLFIRIntrinsics // PASSES-NEXT: InlineElementals // PASSES-NEXT: 'func.func' Pipeline // PASSES-NEXT: SimplifyHLFIRIntrinsics // PASSES-NEXT: InlineElementals -// PASSES-NEXT: 'gpu.module' Pipeline -// PASSES-NEXT: SimplifyHLFIRIntrinsics -// PASSES-NEXT: InlineElementals // PASSES-NEXT: 'omp.declare_reduction' Pipeline // PASSES-NEXT: SimplifyHLFIRIntrinsics // PASSES-NEXT: InlineElementals @@ -37,13 +34,11 @@ func.func @_QQmain() { // PASSES-NEXT: CSE // PASSES-NEXT: (S) 0 num-cse'd - Number of operations CSE'd // PASSES-NEXT: (S) 0 num-dce'd - Number of operations DCE'd -// PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +// PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] // PASSES-NEXT: 'fir.global' Pipeline // PASSES-NEXT: OptimizedBufferization // PASSES-NEXT: 'func.func' Pipeline // PASSES-NEXT: OptimizedBufferization -// PASSES-NEXT: 'gpu.module' Pipeline -// PASSES-NEXT: OptimizedBufferization // PASSES-NEXT: 'omp.declare_reduction' Pipeline // PASSES-NEXT: OptimizedBufferization // PASSES-NEXT: 'omp.private' Pipeline @@ -57,14 +52,12 @@ func.func @_QQmain() { // PASSES-NEXT: (S) 0 num-cse'd - Number of operations CSE'd // PASSES-NEXT: (S) 0 num-dce'd - Number of operations DCE'd -// PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +// PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] // PASSES-NEXT: 'fir.global' Pipeline // PASSES-NEXT: CharacterConversion // PASSES-NEXT: 'func.func' Pipeline // PASSES-NEXT: ArrayValueCopy // PASSES-NEXT: CharacterConversion -// PASSES-NEXT: 'gpu.module' Pipeline -// PASSES-NEXT: CharacterConversion // PASSES-NEXT: 'omp.declare_reduction' Pipeline // PASSES-NEXT: CharacterConversion // PASSES-NEXT: 'omp.private' Pipeline @@ -91,16 +84,13 @@ func.func @_QQmain() { // PASSES-NEXT: AssumedRankOpConversion // PASSES-NEXT: AddAliasTags -// PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'gpu.module', 'omp.declare_reduction', 'omp.private'] +// PASSES-NEXT: Pipeline Collection : ['fir.global', 'func.func', 'omp.declare_reduction', 'omp.private'] // PASSES-NEXT: 'fir.global' Pipeline // PASSES-NEXT: StackReclaim // PASSES-NEXT: CFGConversion // PASSES-NEXT: 'func.func' Pipeline // PASSES-NEXT: StackReclaim // PASSES-NEXT: CFGConversion -// PASSES-NEXT: 'gpu.module' Pipeline -// PASSES-NEXT: StackReclaim -// PASSES-NEXT: CFGConversion // PASSES-NEXT: 'omp.declare_reduction' Pipeline // PASSES-NEXT: StackReclaim // PASSES-NEXT: CFGConversion @@ -122,7 +112,11 @@ func.func @_QQmain() { // PASSES-NEXT: 'func.func' Pipeline // PASSES-NEXT: AbstractResultOpt // PASSES-NEXT: 'gpu.module' Pipeline -// PASSES-NEXT: AbstractResultOpt +// PASSES-NEXT: Pipeline Collection : ['func.func', 'gpu.func'] +// PASSES-NEXT: 'func.func' Pipeline +// PASSES-NEXT: AbstractResultOpt +// PASSES-NEXT: 'gpu.func' Pipeline +// PASSES-NEXT: AbstractResultOpt // PASSES-NEXT: 'omp.declare_reduction' Pipeline // PASSES-NEXT: AbstractResultOpt // PASSES-NEXT: 'omp.private' Pipeline diff --git a/flang/test/Fir/boxproc-2.fir b/flang/test/Fir/boxproc-2.fir index 84132f89afebb..963dfa03663cb 100644 --- a/flang/test/Fir/boxproc-2.fir +++ b/flang/test/Fir/boxproc-2.fir @@ -13,6 +13,9 @@ func.func private @test3(!fir.boxproc<() -> (!fir.type)>) -> no //CHECK-LABEL: func.func private @test5(((i32) -> f32) -> ()) func.func private @test5(!fir.boxproc<(!fir.boxproc<(i32) -> (f32)>) -> ()>) +//CHECK-LABEL: func.func private @test6(!fir.tdesc>) -> !fir.class>>,source_p:(!fir.class>, !fir.ref) -> !fir.class>>}>,c:!fir.box>>,dx:f32,dy:f32}>>) -> !fir.ref +func.func private @test6(!fir.tdesc>) -> !fir.class>>>,source_p:!fir.boxproc<(!fir.class>, !fir.ref) -> !fir.class>>>}>,c:!fir.box>>,dx:f32,dy:f32}>>) -> !fir.ref + // CHECK-LABEL: func.func @proc_pointer_component( // CHECK-SAME: %[[VAL_0:.*]]: (!fir.ref) -> f32, // CHECK-SAME: %[[VAL_1:.*]]: !fir.ref) { diff --git a/flang/test/Fir/boxproc-openmp.fir b/flang/test/Fir/boxproc-openmp.fir new file mode 100644 index 0000000000000..8b714539b5e85 --- /dev/null +++ b/flang/test/Fir/boxproc-openmp.fir @@ -0,0 +1,87 @@ +// RUN: fir-opt --boxed-procedure %s | FileCheck %s +// Test the boxed procedure pass with OpenMP declaration operations. +// Check minimally, only arguments, yields and the private types. + +// Test a private declaration with one region (alloc) +//CHECK: omp.private {type = private} @_QFsub1Et1_private_ref_rec__QFsub1Tt : !fir.ref ()}>> alloc { +omp.private {type = private} @_QFsub1Et1_private_ref_rec__QFsub1Tt : !fir.ref ()>}>> alloc { +//CHECK: ^bb0(%{{.*}}: !fir.ref ()}>>): +^bb0(%arg0: !fir.ref ()>}>>): + %c1_i32 = arith.constant 1 : i32 + %0 = fir.alloca !fir.type<_QFsub1Tt{p1:!fir.boxproc<() -> ()>}> {bindc_name = "t1", pinned, uniq_name = "_QFsub1Et1"} + %1 = fir.declare %0 {uniq_name = "_QFsub1Et1"} : (!fir.ref ()>}>>) -> !fir.ref ()>}>> + %2 = fir.embox %1 : (!fir.ref ()>}>>) -> !fir.box ()>}>> + %3 = fir.address_of(@_QQclXea6256ba131ddd9c2210e68030a0edd3) : !fir.ref> + %4 = fir.convert %2 : (!fir.box ()>}>>) -> !fir.box + %5 = fir.convert %3 : (!fir.ref>) -> !fir.ref + %6 = fir.call @_FortranAInitialize(%4, %5, %c1_i32) fastmath : (!fir.box, !fir.ref, i32) -> none +//CHECK: omp.yield(%{{.*}} : !fir.ref ()}>>) + omp.yield(%1 : !fir.ref ()>}>>) +} +func.func @_QPsub1() { + %0 = fir.alloca !fir.type<_QFsub1Tt{p1:!fir.boxproc<() -> ()>}> {bindc_name = "t1", uniq_name = "_QFsub1Et1"} + %1 = fir.declare %0 {uniq_name = "_QFsub1Et1"} : (!fir.ref ()>}>>) -> !fir.ref ()>}>> +//CHECK: omp.parallel private(@_QFsub1Et1_private_ref_rec__QFsub1Tt %{{.*}} -> %{{.*}} : !fir.ref ()}>>) { + omp.parallel private(@_QFsub1Et1_private_ref_rec__QFsub1Tt %1 -> %arg0 : !fir.ref ()>}>>) { + %2 = fir.declare %arg0 {uniq_name = "_QFsub1Et1"} : (!fir.ref ()>}>>) -> !fir.ref ()>}>> + omp.terminator + } + return +} + + +// Test a private declaration with all regions (alloc, copy, dealloc) +//CHECK: omp.private {type = firstprivate} @_QFsub2Et1_firstprivate_ref_box_heap_rec__QFsub2Tt : +//CHECK-SAME: !fir.ref ()}>>>> alloc { +omp.private {type = firstprivate} @_QFsub2Et1_firstprivate_ref_box_heap_rec__QFsub2Tt : !fir.ref ()>}>>>> alloc { +//CHECK: ^bb0(%{{.*}}: !fir.ref ()}>>>>): +^bb0(%arg0: !fir.ref ()>}>>>>): + %0 = fir.alloca !fir.box ()>}>>> {bindc_name = "t1", pinned, uniq_name = "_QFsub2Et1"} + %1 = fir.declare %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFsub2Et1"} : (!fir.ref ()>}>>>>) -> !fir.ref ()>}>>>> +//CHECK: omp.yield(%{{.*}} : !fir.ref ()}>>>>) + omp.yield(%1 : !fir.ref ()>}>>>>) +} copy { +//CHECK: ^bb0(%{{.*}}: !fir.ref ()}>>>>, +//CHECK-SAME: %{{.*}}: !fir.ref ()}>>>>): +^bb0(%arg0: !fir.ref ()>}>>>>, %arg1: !fir.ref ()>}>>>>): + %c5_i32 = arith.constant 5 : i32 + %0 = fir.load %arg0 : !fir.ref ()>}>>>> + %1 = fir.box_addr %0 : (!fir.box ()>}>>>) -> !fir.heap ()>}>> + %2 = fir.embox %1 : (!fir.heap ()>}>>) -> !fir.box ()>}>> + %3 = fir.address_of(@_QQclXea) : !fir.ref> + %4 = fir.convert %arg1 : (!fir.ref ()>}>>>>) -> !fir.ref> + %5 = fir.convert %2 : (!fir.box ()>}>>) -> !fir.box + %6 = fir.convert %3 : (!fir.ref>) -> !fir.ref + %7 = fir.call @_FortranAAssign(%4, %5, %6, %c5_i32) : (!fir.ref>, !fir.box, !fir.ref, i32) -> none +//CHECK: omp.yield(%{{.*}} : !fir.ref ()}>>>>) + omp.yield(%arg1 : !fir.ref ()>}>>>>) +} dealloc { +//CHECK: ^bb0(%{{.*}}: !fir.ref ()}>>>>): +^bb0(%arg0: !fir.ref ()>}>>>>): + %c5_i32 = arith.constant 5 : i32 + %false = arith.constant false + %0 = fir.absent !fir.box + %1 = fir.address_of(@_QQclXea) : !fir.ref> + %2 = fir.convert %arg0 : (!fir.ref ()>}>>>>) -> !fir.ref> + %3 = fir.convert %1 : (!fir.ref>) -> !fir.ref + %4 = fir.call @_FortranAAllocatableDeallocate(%2, %false, %0, %3, %c5_i32) fastmath : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 + omp.yield +} +func.func @_QPsub2() { + %0 = fir.alloca !fir.box ()>}>>> {bindc_name = "t1", uniq_name = "_QFsub2Et1"} + %1 = fir.declare %0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFsub2Et1"} : (!fir.ref ()>}>>>>) -> !fir.ref ()>}>>>> +//CHECK: omp.parallel private(@_QFsub2Et1_firstprivate_ref_box_heap_rec__QFsub2Tt %{{.*}} -> %{{.*}} : +//CHECK-SAME: !fir.ref ()}>>>>) { + omp.parallel private(@_QFsub2Et1_firstprivate_ref_box_heap_rec__QFsub2Tt %1 -> %arg0 : !fir.ref ()>}>>>>) { + %2 = fir.declare %arg0 {fortran_attrs = #fir.var_attrs, uniq_name = "_QFsub2Et1"} : (!fir.ref ()>}>>>>) -> !fir.ref ()>}>>>> + omp.terminator + } + return +} +func.func private @_FortranAInitialize(!fir.box, !fir.ref, i32) -> none attributes {fir.runtime} +fir.global linkonce @_QQclXea constant : !fir.char<1,8> { + %0 = fir.string_lit "pp.f90\00"(8) : !fir.char<1,8> + fir.has_value %0 : !fir.char<1,8> +} +func.func private @_FortranAAllocatableDeallocate(!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 attributes {fir.runtime} +func.func private @_FortranAAssign(!fir.ref>, !fir.box, !fir.ref, i32) -> none attributes {fir.runtime} diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir index c1a35e88f580d..c48a605a1b2a9 100644 --- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir +++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir @@ -358,10 +358,10 @@ func.func @_QPopenmp_target_data_region() { %9 = arith.subi %8, %c1_i64 : i64 %10 = fir.coordinate_of %0, %9 : (!fir.ref>, i64) -> !fir.ref fir.store %6 to %10 : !fir.ref - %11 = arith.addi %arg0, %c1 : index + %11 = arith.addi %arg0, %c1 overflow : index %12 = fir.convert %c1 : (index) -> i32 %13 = fir.load %1 : !fir.ref - %14 = arith.addi %13, %12 : i32 + %14 = arith.addi %13, %12 overflow : i32 fir.result %11, %14 : index, i32 } fir.store %5#1 to %1 : !fir.ref @@ -404,11 +404,11 @@ func.func @_QPopenmp_target_data_region() { // CHECK: %[[VAL_21:.*]] = llvm.sub %[[VAL_19]], %[[VAL_20]] : i64 // CHECK: %[[VAL_22:.*]] = llvm.getelementptr %[[VAL_1]][0, %[[VAL_21]]] : (!llvm.ptr, i64) -> !llvm.ptr // CHECK: llvm.store %[[VAL_17]], %[[VAL_22]] : i32, !llvm.ptr -// CHECK: %[[VAL_23:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] : i64 +// CHECK: %[[VAL_23:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] overflow : i64 // CHECK: %[[VAL_24:.*]] = llvm.trunc %[[VAL_8]] : i64 to i32 // CHECK: %[[VAL_25:.*]] = llvm.load %[[VAL_3]] : !llvm.ptr -> i32 -// CHECK: %[[VAL_26:.*]] = llvm.add %[[VAL_25]], %[[VAL_24]] : i32 -// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] : i64 +// CHECK: %[[VAL_26:.*]] = llvm.add %[[VAL_25]], %[[VAL_24]] overflow : i32 +// CHECK: %[[VAL_27:.*]] = llvm.add %[[VAL_12]], %[[VAL_8]] overflow : i64 // CHECK: %[[VAL_28:.*]] = llvm.mlir.constant(1 : index) : i64 // CHECK: %[[VAL_29:.*]] = llvm.sub %[[VAL_14]], %[[VAL_28]] : i64 // CHECK: llvm.br ^bb1(%[[VAL_27]], %[[VAL_26]], %[[VAL_29]] : i64, i32, i64) diff --git a/flang/test/Fir/loop01.fir b/flang/test/Fir/loop01.fir index c1cbb522c378c..30d10b9bbdb97 100644 --- a/flang/test/Fir/loop01.fir +++ b/flang/test/Fir/loop01.fir @@ -1,5 +1,7 @@ // RUN: fir-opt --split-input-file --cfg-conversion %s | FileCheck %s -// RUN: fir-opt --split-input-file --cfg-conversion="set-nsw=true" %s | FileCheck %s --check-prefix=NSW +// RUN: fir-opt --split-input-file --cfg-conversion="set-nsw=false" %s | FileCheck %s --check-prefix=NO-NSW + +// NO-NSW-NOT: overflow func.func @x(%lb : index, %ub : index, %step : index, %b : i1, %addr : !fir.ref) { fir.do_loop %iv = %lb to %ub step %step unordered { @@ -35,7 +37,7 @@ func.func private @f2() -> i1 // CHECK: fir.store %[[VAL_12]] to %[[VAL_4]] : !fir.ref // CHECK: br ^bb5 // CHECK: ^bb5: -// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_8]], %[[VAL_2]] : index +// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_8]], %[[VAL_2]] overflow : index // CHECK: %[[VAL_14:.*]] = arith.constant 1 : index // CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_9]], %[[VAL_14]] : index // CHECK: br ^bb1(%[[VAL_13]], %[[VAL_15]] : index, index) @@ -44,34 +46,6 @@ func.func private @f2() -> i1 // CHECK: } // CHECK: func private @f2() -> i1 -// NSW: func @x(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: index, %[[VAL_3:.*]]: i1, %[[VAL_4:.*]]: !fir.ref) { -// NSW: %[[VAL_5:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index -// NSW: %[[VAL_6:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] : index -// NSW: %[[VAL_7:.*]] = arith.divsi %[[VAL_6]], %[[VAL_2]] : index -// NSW: br ^bb1(%[[VAL_0]], %[[VAL_7]] : index, index) -// NSW: ^bb1(%[[VAL_8:.*]]: index, %[[VAL_9:.*]]: index): -// NSW: %[[VAL_10:.*]] = arith.constant 0 : index -// NSW: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[VAL_10]] : index -// NSW: cond_br %[[VAL_11]], ^bb2, ^bb6 -// NSW: ^bb2: -// NSW: cond_br %[[VAL_3]], ^bb3, ^bb4 -// NSW: ^bb3: -// NSW: fir.store %[[VAL_8]] to %[[VAL_4]] : !fir.ref -// NSW: br ^bb5 -// NSW: ^bb4: -// NSW: %[[VAL_12:.*]] = arith.constant 0 : index -// NSW: fir.store %[[VAL_12]] to %[[VAL_4]] : !fir.ref -// NSW: br ^bb5 -// NSW: ^bb5: -// NSW: %[[VAL_13:.*]] = arith.addi %[[VAL_8]], %[[VAL_2]] overflow : index -// NSW: %[[VAL_14:.*]] = arith.constant 1 : index -// NSW: %[[VAL_15:.*]] = arith.subi %[[VAL_9]], %[[VAL_14]] : index -// NSW: br ^bb1(%[[VAL_13]], %[[VAL_15]] : index, index) -// NSW: ^bb6: -// NSW: return -// NSW: } -// NSW: func private @f2() -> i1 - // ----- func.func @x2(%lo : index, %up : index, %ok : i1) { @@ -101,36 +75,13 @@ func.func private @f3(i16) // CHECK: cond_br %[[VAL_14]], ^bb2, ^bb3 // CHECK: ^bb2: // CHECK: %[[VAL_15:.*]] = fir.call @f2() : () -> i1 -// CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_4]], %[[VAL_3]] : index +// CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_4]], %[[VAL_3]] overflow : index // CHECK: br ^bb1(%[[VAL_16]], %[[VAL_15]] : index, i1) // CHECK: ^bb3: // CHECK: return // CHECK: } // CHECK: func private @f3(i16) -// NSW: func @x2(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: i1) { -// NSW: %[[VAL_3:.*]] = arith.constant 1 : index -// NSW: br ^bb1(%[[VAL_0]], %[[VAL_2]] : index, i1) -// NSW: ^bb1(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: i1): -// NSW: %[[VAL_6:.*]] = arith.constant 0 : index -// NSW: %[[VAL_7:.*]] = arith.cmpi slt, %[[VAL_6]], %[[VAL_3]] : index -// NSW: %[[VAL_8:.*]] = arith.cmpi sle, %[[VAL_4]], %[[VAL_1]] : index -// NSW: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_3]], %[[VAL_6]] : index -// NSW: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_4]] : index -// NSW: %[[VAL_11:.*]] = arith.andi %[[VAL_7]], %[[VAL_8]] : i1 -// NSW: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1 -// NSW: %[[VAL_13:.*]] = arith.ori %[[VAL_11]], %[[VAL_12]] : i1 -// NSW: %[[VAL_14:.*]] = arith.andi %[[VAL_5]], %[[VAL_13]] : i1 -// NSW: cond_br %[[VAL_14]], ^bb2, ^bb3 -// NSW: ^bb2: -// NSW: %[[VAL_15:.*]] = fir.call @f2() : () -> i1 -// NSW: %[[VAL_16:.*]] = arith.addi %[[VAL_4]], %[[VAL_3]] overflow : index -// NSW: br ^bb1(%[[VAL_16]], %[[VAL_15]] : index, i1) -// NSW: ^bb3: -// NSW: return -// NSW: } -// NSW: func private @f3(i16) - // ----- // do_loop with an extra loop-carried value @@ -159,7 +110,7 @@ func.func @x3(%lo : index, %up : index) -> i1 { // CHECK: cond_br %[[VAL_11]], ^bb2, ^bb3 // CHECK: ^bb2: // CHECK: %[[VAL_12:.*]] = fir.call @f2() : () -> i1 -// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_7]], %[[VAL_2]] : index +// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_7]], %[[VAL_2]] overflow : index // CHECK: %[[VAL_14:.*]] = arith.constant 1 : index // CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_9]], %[[VAL_14]] : index // CHECK: br ^bb1(%[[VAL_13]], %[[VAL_12]], %[[VAL_15]] : index, i1, index) @@ -167,29 +118,6 @@ func.func @x3(%lo : index, %up : index) -> i1 { // CHECK: return %[[VAL_8]] : i1 // CHECK: } -// NSW-LABEL: func @x3( -// NSW-SAME: %[[VAL_0:.*]]: index, -// NSW-SAME: %[[VAL_1:.*]]: index) -> i1 { -// NSW: %[[VAL_2:.*]] = arith.constant 1 : index -// NSW: %[[VAL_3:.*]] = arith.constant true -// NSW: %[[VAL_4:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index -// NSW: %[[VAL_5:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] : index -// NSW: %[[VAL_6:.*]] = arith.divsi %[[VAL_5]], %[[VAL_2]] : index -// NSW: br ^bb1(%[[VAL_0]], %[[VAL_3]], %[[VAL_6]] : index, i1, index) -// NSW: ^bb1(%[[VAL_7:.*]]: index, %[[VAL_8:.*]]: i1, %[[VAL_9:.*]]: index): -// NSW: %[[VAL_10:.*]] = arith.constant 0 : index -// NSW: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[VAL_10]] : index -// NSW: cond_br %[[VAL_11]], ^bb2, ^bb3 -// NSW: ^bb2: -// NSW: %[[VAL_12:.*]] = fir.call @f2() : () -> i1 -// NSW: %[[VAL_13:.*]] = arith.addi %[[VAL_7]], %[[VAL_2]] overflow : index -// NSW: %[[VAL_14:.*]] = arith.constant 1 : index -// NSW: %[[VAL_15:.*]] = arith.subi %[[VAL_9]], %[[VAL_14]] : index -// NSW: br ^bb1(%[[VAL_13]], %[[VAL_12]], %[[VAL_15]] : index, i1, index) -// NSW: ^bb3: -// NSW: return %[[VAL_8]] : i1 -// NSW: } - // ----- // iterate_while with an extra loop-carried value @@ -227,7 +155,7 @@ func.func private @f4(i32) -> i1 // CHECK: cond_br %[[VAL_16]], ^bb2, ^bb3 // CHECK: ^bb2: // CHECK: %[[VAL_17:.*]] = fir.call @f2() : () -> i1 -// CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] : index +// CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] overflow : index // CHECK: br ^bb1(%[[VAL_18]], %[[VAL_6]], %[[VAL_17]] : index, i1, i1) // CHECK: ^bb3: // CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_6]], %[[VAL_7]] : i1 @@ -235,34 +163,6 @@ func.func private @f4(i32) -> i1 // CHECK: } // CHECK: func private @f4(i32) -> i1 -// NSW-LABEL: func @y3( -// NSW-SAME: %[[VAL_0:.*]]: index, -// NSW-SAME: %[[VAL_1:.*]]: index) -> i1 { -// NSW: %[[VAL_2:.*]] = arith.constant 1 : index -// NSW: %[[VAL_3:.*]] = arith.constant true -// NSW: %[[VAL_4:.*]] = fir.call @f2() : () -> i1 -// NSW: br ^bb1(%[[VAL_0]], %[[VAL_3]], %[[VAL_4]] : index, i1, i1) -// NSW: ^bb1(%[[VAL_5:.*]]: index, %[[VAL_6:.*]]: i1, %[[VAL_7:.*]]: i1): -// NSW: %[[VAL_8:.*]] = arith.constant 0 : index -// NSW: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_8]], %[[VAL_2]] : index -// NSW: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_5]], %[[VAL_1]] : index -// NSW: %[[VAL_11:.*]] = arith.cmpi slt, %[[VAL_2]], %[[VAL_8]] : index -// NSW: %[[VAL_12:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_5]] : index -// NSW: %[[VAL_13:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1 -// NSW: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_12]] : i1 -// NSW: %[[VAL_15:.*]] = arith.ori %[[VAL_13]], %[[VAL_14]] : i1 -// NSW: %[[VAL_16:.*]] = arith.andi %[[VAL_6]], %[[VAL_15]] : i1 -// NSW: cond_br %[[VAL_16]], ^bb2, ^bb3 -// NSW: ^bb2: -// NSW: %[[VAL_17:.*]] = fir.call @f2() : () -> i1 -// NSW: %[[VAL_18:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] overflow : index -// NSW: br ^bb1(%[[VAL_18]], %[[VAL_6]], %[[VAL_17]] : index, i1, i1) -// NSW: ^bb3: -// NSW: %[[VAL_19:.*]] = arith.andi %[[VAL_6]], %[[VAL_7]] : i1 -// NSW: return %[[VAL_19]] : i1 -// NSW: } -// NSW: func private @f4(i32) -> i1 - // ----- // do_loop that returns the final value of the induction @@ -291,7 +191,7 @@ func.func @x4(%lo : index, %up : index) -> index { // CHECK: ^bb2: // CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_6]] : (index) -> i32 // CHECK: %[[VAL_11:.*]] = fir.call @f4(%[[VAL_10]]) : (i32) -> i1 -// CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_6]], %[[VAL_2]] : index +// CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_6]], %[[VAL_2]] overflow : index // CHECK: %[[VAL_13:.*]] = arith.constant 1 : index // CHECK: %[[VAL_14:.*]] = arith.subi %[[VAL_7]], %[[VAL_13]] : index // CHECK: br ^bb1(%[[VAL_12]], %[[VAL_14]] : index, index) @@ -299,29 +199,6 @@ func.func @x4(%lo : index, %up : index) -> index { // CHECK: return %[[VAL_6]] : index // CHECK: } -// NSW-LABEL: func @x4( -// NSW-SAME: %[[VAL_0:.*]]: index, -// NSW-SAME: %[[VAL_1:.*]]: index) -> index { -// NSW: %[[VAL_2:.*]] = arith.constant 1 : index -// NSW: %[[VAL_3:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index -// NSW: %[[VAL_4:.*]] = arith.addi %[[VAL_3]], %[[VAL_2]] : index -// NSW: %[[VAL_5:.*]] = arith.divsi %[[VAL_4]], %[[VAL_2]] : index -// NSW: br ^bb1(%[[VAL_0]], %[[VAL_5]] : index, index) -// NSW: ^bb1(%[[VAL_6:.*]]: index, %[[VAL_7:.*]]: index): -// NSW: %[[VAL_8:.*]] = arith.constant 0 : index -// NSW: %[[VAL_9:.*]] = arith.cmpi sgt, %[[VAL_7]], %[[VAL_8]] : index -// NSW: cond_br %[[VAL_9]], ^bb2, ^bb3 -// NSW: ^bb2: -// NSW: %[[VAL_10:.*]] = fir.convert %[[VAL_6]] : (index) -> i32 -// NSW: %[[VAL_11:.*]] = fir.call @f4(%[[VAL_10]]) : (i32) -> i1 -// NSW: %[[VAL_12:.*]] = arith.addi %[[VAL_6]], %[[VAL_2]] overflow : index -// NSW: %[[VAL_13:.*]] = arith.constant 1 : index -// NSW: %[[VAL_14:.*]] = arith.subi %[[VAL_7]], %[[VAL_13]] : index -// NSW: br ^bb1(%[[VAL_12]], %[[VAL_14]] : index, index) -// NSW: ^bb3: -// NSW: return %[[VAL_6]] : index -// NSW: } - // ----- // iterate_while that returns the final value of both inductions @@ -356,38 +233,12 @@ func.func @y4(%lo : index, %up : index) -> index { // CHECK: ^bb2: // CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_4]] : (index) -> i32 // CHECK: %[[VAL_16:.*]] = fir.call @f4(%[[VAL_15]]) : (i32) -> i1 -// CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] : index +// CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] overflow : index // CHECK: br ^bb1(%[[VAL_17]], %[[VAL_16]] : index, i1) // CHECK: ^bb3: // CHECK: return %[[VAL_4]] : index // CHECK: } -// NSW-LABEL: func @y4( -// NSW-SAME: %[[VAL_0:.*]]: index, -// NSW-SAME: %[[VAL_1:.*]]: index) -> index { -// NSW: %[[VAL_2:.*]] = arith.constant 1 : index -// NSW: %[[VAL_3:.*]] = arith.constant true -// NSW: br ^bb1(%[[VAL_0]], %[[VAL_3]] : index, i1) -// NSW: ^bb1(%[[VAL_4:.*]]: index, %[[VAL_5:.*]]: i1): -// NSW: %[[VAL_6:.*]] = arith.constant 0 : index -// NSW: %[[VAL_7:.*]] = arith.cmpi slt, %[[VAL_6]], %[[VAL_2]] : index -// NSW: %[[VAL_8:.*]] = arith.cmpi sle, %[[VAL_4]], %[[VAL_1]] : index -// NSW: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_2]], %[[VAL_6]] : index -// NSW: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_4]] : index -// NSW: %[[VAL_11:.*]] = arith.andi %[[VAL_7]], %[[VAL_8]] : i1 -// NSW: %[[VAL_12:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1 -// NSW: %[[VAL_13:.*]] = arith.ori %[[VAL_11]], %[[VAL_12]] : i1 -// NSW: %[[VAL_14:.*]] = arith.andi %[[VAL_5]], %[[VAL_13]] : i1 -// NSW: cond_br %[[VAL_14]], ^bb2, ^bb3 -// NSW: ^bb2: -// NSW: %[[VAL_15:.*]] = fir.convert %[[VAL_4]] : (index) -> i32 -// NSW: %[[VAL_16:.*]] = fir.call @f4(%[[VAL_15]]) : (i32) -> i1 -// NSW: %[[VAL_17:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] overflow : index -// NSW: br ^bb1(%[[VAL_17]], %[[VAL_16]] : index, i1) -// NSW: ^bb3: -// NSW: return %[[VAL_4]] : index -// NSW: } - // ----- // do_loop that returns the final induction value @@ -420,7 +271,7 @@ func.func @x5(%lo : index, %up : index) -> index { // CHECK: ^bb2: // CHECK: %[[VAL_12:.*]] = fir.call @f2() : () -> i1 // CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i1) -> i16 -// CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_7]], %[[VAL_2]] : index +// CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_7]], %[[VAL_2]] overflow : index // CHECK: %[[VAL_15:.*]] = arith.constant 1 : index // CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_9]], %[[VAL_15]] : index // CHECK: br ^bb1(%[[VAL_14]], %[[VAL_13]], %[[VAL_16]] : index, i16, index) @@ -429,31 +280,6 @@ func.func @x5(%lo : index, %up : index) -> index { // CHECK: return %[[VAL_7]] : index // CHECK: } -// NSW-LABEL: func @x5( -// NSW-SAME: %[[VAL_0:.*]]: index, -// NSW-SAME: %[[VAL_1:.*]]: index) -> index { -// NSW: %[[VAL_2:.*]] = arith.constant 1 : index -// NSW: %[[VAL_3:.*]] = arith.constant 42 : i16 -// NSW: %[[VAL_4:.*]] = arith.subi %[[VAL_1]], %[[VAL_0]] : index -// NSW: %[[VAL_5:.*]] = arith.addi %[[VAL_4]], %[[VAL_2]] : index -// NSW: %[[VAL_6:.*]] = arith.divsi %[[VAL_5]], %[[VAL_2]] : index -// NSW: br ^bb1(%[[VAL_0]], %[[VAL_3]], %[[VAL_6]] : index, i16, index) -// NSW: ^bb1(%[[VAL_7:.*]]: index, %[[VAL_8:.*]]: i16, %[[VAL_9:.*]]: index): -// NSW: %[[VAL_10:.*]] = arith.constant 0 : index -// NSW: %[[VAL_11:.*]] = arith.cmpi sgt, %[[VAL_9]], %[[VAL_10]] : index -// NSW: cond_br %[[VAL_11]], ^bb2, ^bb3 -// NSW: ^bb2: -// NSW: %[[VAL_12:.*]] = fir.call @f2() : () -> i1 -// NSW: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (i1) -> i16 -// NSW: %[[VAL_14:.*]] = arith.addi %[[VAL_7]], %[[VAL_2]] overflow : index -// NSW: %[[VAL_15:.*]] = arith.constant 1 : index -// NSW: %[[VAL_16:.*]] = arith.subi %[[VAL_9]], %[[VAL_15]] : index -// NSW: br ^bb1(%[[VAL_14]], %[[VAL_13]], %[[VAL_16]] : index, i16, index) -// NSW: ^bb3: -// NSW: fir.call @f3(%[[VAL_8]]) : (i16) -> () -// NSW: return %[[VAL_7]] : index -// NSW: } - // ----- // iterate_while that returns the both induction values @@ -496,7 +322,7 @@ func.func @y5(%lo : index, %up : index) -> index { // CHECK: ^bb2: // CHECK: %[[VAL_17:.*]] = fir.call @f2() : () -> i1 // CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i1) -> i16 -// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] : index +// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] overflow : index // CHECK: br ^bb1(%[[VAL_19]], %[[VAL_17]], %[[VAL_18]] : index, i1, i16) // CHECK: ^bb3: // CHECK: cond_br %[[VAL_6]], ^bb4, ^bb5 @@ -508,37 +334,3 @@ func.func @y5(%lo : index, %up : index) -> index { // CHECK: fir.call @f3(%[[VAL_7]]) : (i16) -> () // CHECK: return %[[VAL_5]] : index // CHECK: } - -// NSW-LABEL: func @y5( -// NSW-SAME: %[[VAL_0:.*]]: index, -// NSW-SAME: %[[VAL_1:.*]]: index) -> index { -// NSW: %[[VAL_2:.*]] = arith.constant 1 : index -// NSW: %[[VAL_3:.*]] = arith.constant 42 : i16 -// NSW: %[[VAL_4:.*]] = arith.constant true -// NSW: br ^bb1(%[[VAL_0]], %[[VAL_4]], %[[VAL_3]] : index, i1, i16) -// NSW: ^bb1(%[[VAL_5:.*]]: index, %[[VAL_6:.*]]: i1, %[[VAL_7:.*]]: i16): -// NSW: %[[VAL_8:.*]] = arith.constant 0 : index -// NSW: %[[VAL_9:.*]] = arith.cmpi slt, %[[VAL_8]], %[[VAL_2]] : index -// NSW: %[[VAL_10:.*]] = arith.cmpi sle, %[[VAL_5]], %[[VAL_1]] : index -// NSW: %[[VAL_11:.*]] = arith.cmpi slt, %[[VAL_2]], %[[VAL_8]] : index -// NSW: %[[VAL_12:.*]] = arith.cmpi sle, %[[VAL_1]], %[[VAL_5]] : index -// NSW: %[[VAL_13:.*]] = arith.andi %[[VAL_9]], %[[VAL_10]] : i1 -// NSW: %[[VAL_14:.*]] = arith.andi %[[VAL_11]], %[[VAL_12]] : i1 -// NSW: %[[VAL_15:.*]] = arith.ori %[[VAL_13]], %[[VAL_14]] : i1 -// NSW: %[[VAL_16:.*]] = arith.andi %[[VAL_6]], %[[VAL_15]] : i1 -// NSW: cond_br %[[VAL_16]], ^bb2, ^bb3 -// NSW: ^bb2: -// NSW: %[[VAL_17:.*]] = fir.call @f2() : () -> i1 -// NSW: %[[VAL_18:.*]] = fir.convert %[[VAL_17]] : (i1) -> i16 -// NSW: %[[VAL_19:.*]] = arith.addi %[[VAL_5]], %[[VAL_2]] overflow : index -// NSW: br ^bb1(%[[VAL_19]], %[[VAL_17]], %[[VAL_18]] : index, i1, i16) -// NSW: ^bb3: -// NSW: cond_br %[[VAL_6]], ^bb4, ^bb5 -// NSW: ^bb4: -// NSW: %[[VAL_20:.*]] = arith.constant 0 : i32 -// NSW: %[[VAL_21:.*]] = fir.call @f4(%[[VAL_20]]) : (i32) -> i1 -// NSW: br ^bb5 -// NSW: ^bb5: -// NSW: fir.call @f3(%[[VAL_7]]) : (i16) -> () -// NSW: return %[[VAL_5]] : index -// NSW: } diff --git a/flang/test/Fir/loop02.fir b/flang/test/Fir/loop02.fir index 50948e0e7aa6b..fb209a9dfeb42 100644 --- a/flang/test/Fir/loop02.fir +++ b/flang/test/Fir/loop02.fir @@ -31,7 +31,7 @@ func.func private @y(%addr : !fir.ref) // CHECK: cond_br %[[VAL_13]], ^bb2, ^bb3 // CHECK: ^bb2: // CHECK: fir.call @y(%[[VAL_0]]) : (!fir.ref) -> () -// CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_10]], %[[VAL_2]] : index +// CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_10]], %[[VAL_2]] overflow : index // CHECK: %[[VAL_15:.*]] = arith.constant 1 : index // CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_11]], %[[VAL_15]] : index // CHECK: br ^bb1(%[[VAL_14]], %[[VAL_16]] : index, index) @@ -54,7 +54,7 @@ func.func private @y(%addr : !fir.ref) // NOOPT: cond_br %[[VAL_9]], ^bb2, ^bb3 // NOOPT: ^bb2: // NOOPT: fir.call @y(%[[VAL_0]]) : (!fir.ref) -> () -// NOOPT: %[[VAL_10:.*]] = arith.addi %[[VAL_6]], %[[VAL_2]] : index +// NOOPT: %[[VAL_10:.*]] = arith.addi %[[VAL_6]], %[[VAL_2]] overflow : index // NOOPT: %[[VAL_11:.*]] = arith.constant 1 : index // NOOPT: %[[VAL_12:.*]] = arith.subi %[[VAL_7]], %[[VAL_11]] : index // NOOPT: br ^bb1(%[[VAL_10]], %[[VAL_12]] : index, index) diff --git a/flang/test/HLFIR/cshift-lowering.fir b/flang/test/HLFIR/cshift-lowering.fir new file mode 100644 index 0000000000000..386b81c4dbff6 --- /dev/null +++ b/flang/test/HLFIR/cshift-lowering.fir @@ -0,0 +1,217 @@ +// Test hlfir.cshift operation lowering to fir runtime call +// RUN: fir-opt %s -lower-hlfir-intrinsics | FileCheck %s + +// 1d boxed vector shift by scalar +func.func @cshift1(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "sh"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "a"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg1 {uniq_name = "sh"} : (!fir.ref) -> (!fir.ref, !fir.ref) + %2 = hlfir.cshift %0#0 %1#0 : (!fir.box>, !fir.ref) -> !hlfir.expr + hlfir.assign %2 to %0#0 : !hlfir.expr, !fir.box> + return +} +// CHECK-LABEL: func.func @cshift1( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "a"}, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref {fir.bindc_name = "sh"}) { +// CHECK: %[[VAL_2:.*]] = arith.constant true +// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_5:.*]] = fir.alloca !fir.box>> +// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "a"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "sh"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_8:.*]] = fir.zero_bits !fir.heap> +// CHECK: %[[VAL_9:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_10:.*]] = fir.embox %[[VAL_8]](%[[VAL_9]]) : (!fir.heap>, !fir.shape<1>) -> !fir.box>> +// CHECK: fir.store %[[VAL_10]] to %[[VAL_5]] : !fir.ref>>> +// CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_7]]#1 : !fir.ref +// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_5]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_6]]#1 : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_11]] : (i32) -> i64 +// CHECK: %[[VAL_17:.*]] = fir.call @_FortranACshiftVector(%[[VAL_13]], %[[VAL_14]], %[[VAL_15]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, i64, !fir.ref, i32) -> none + +// 2d boxed array shift by scalar +func.func @cshift2(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: i32 {fir.bindc_name = "sh"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "a"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2 = hlfir.cshift %0#0 %arg1 : (!fir.box>, i32) -> !hlfir.expr + hlfir.assign %2 to %0#0 : !hlfir.expr, !fir.box> + return +} +// CHECK-LABEL: func.func @cshift2( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "a"}, +// CHECK-SAME: %[[VAL_1:.*]]: i32 {fir.bindc_name = "sh"}) { +// CHECK: %[[VAL_2:.*]] = arith.constant true +// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_6:.*]] = fir.alloca !fir.box>> +// CHECK: %[[VAL_7:.*]] = fir.alloca i32 +// CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "a"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK: fir.store %[[VAL_1]] to %[[VAL_7]] : !fir.ref +// CHECK: %[[VAL_9:.*]] = fir.zero_bits !fir.heap> +// CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_5]], %[[VAL_5]] : (index, index) -> !fir.shape<2> +// CHECK: %[[VAL_11:.*]] = fir.embox %[[VAL_9]](%[[VAL_10]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> +// CHECK: fir.store %[[VAL_11]] to %[[VAL_6]] : !fir.ref>>> +// CHECK: %[[VAL_12:.*]] = fir.embox %[[VAL_7]] : (!fir.ref) -> !fir.box +// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_6]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_8]]#1 : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_12]] : (!fir.box) -> !fir.box +// CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_4]] : (index) -> i32 +// CHECK: %[[VAL_19:.*]] = fir.call @_FortranACshift(%[[VAL_14]], %[[VAL_15]], %[[VAL_16]], %[[VAL_17]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.box, i32, !fir.ref, i32) -> none + +// 2d boxed array shift by boxed array +func.func @cshift3(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "sh"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "a"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %1:2 = hlfir.declare %arg1 {uniq_name = "sh"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2 = hlfir.cshift %0#0 %1#0 : (!fir.box>, !fir.box>) -> !hlfir.expr + hlfir.assign %2 to %0#0 : !hlfir.expr, !fir.box> + return +} +// CHECK-LABEL: func.func @cshift3( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "a"}, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.box> {fir.bindc_name = "sh"}) { +// CHECK: %[[VAL_2:.*]] = arith.constant true +// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_6:.*]] = fir.alloca !fir.box>> +// CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "a"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK: %[[VAL_8:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "sh"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK: %[[VAL_9:.*]] = fir.zero_bits !fir.heap> +// CHECK: %[[VAL_10:.*]] = fir.shape %[[VAL_5]], %[[VAL_5]] : (index, index) -> !fir.shape<2> +// CHECK: %[[VAL_11:.*]] = fir.embox %[[VAL_9]](%[[VAL_10]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> +// CHECK: fir.store %[[VAL_11]] to %[[VAL_6]] : !fir.ref>>> +// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_6]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_7]]#1 : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_8]]#1 : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_4]] : (index) -> i32 +// CHECK: %[[VAL_18:.*]] = fir.call @_FortranACshift(%[[VAL_13]], %[[VAL_14]], %[[VAL_15]], %[[VAL_16]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.box, i32, !fir.ref, i32) -> none + +// 2d boxed array shift by array expr +func.func @cshift4(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !hlfir.expr {fir.bindc_name = "sh"}) { + %0:2 = hlfir.declare %arg0 {uniq_name = "a"} : (!fir.box>) -> (!fir.box>, !fir.box>) + %2 = hlfir.cshift %0#0 %arg1 : (!fir.box>, !hlfir.expr) -> !hlfir.expr + hlfir.assign %2 to %0#0 : !hlfir.expr, !fir.box> + return +} +// CHECK-LABEL: func.func @cshift4( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "a"}, +// CHECK-SAME: %[[VAL_1:.*]]: !hlfir.expr {fir.bindc_name = "sh"}) { +// CHECK: %[[VAL_2:.*]] = arith.constant true +// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_6:.*]] = fir.alloca !fir.box>> +// CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "a"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK: %[[VAL_8:.*]] = hlfir.shape_of %[[VAL_1]] : (!hlfir.expr) -> !fir.shape<1> +// CHECK: %[[VAL_9:.*]]:3 = hlfir.associate %[[VAL_1]](%[[VAL_8]]) {adapt.valuebyref} : (!hlfir.expr, !fir.shape<1>) -> (!fir.box>, !fir.ref>, i1) +// CHECK: %[[VAL_10:.*]] = hlfir.get_extent %[[VAL_8]] {dim = 0 : index} : (!fir.shape<1>) -> index +// CHECK: %[[VAL_11:.*]] = fir.zero_bits !fir.heap> +// CHECK: %[[VAL_12:.*]] = fir.shape %[[VAL_5]], %[[VAL_5]] : (index, index) -> !fir.shape<2> +// CHECK: %[[VAL_13:.*]] = fir.embox %[[VAL_11]](%[[VAL_12]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> +// CHECK: fir.store %[[VAL_13]] to %[[VAL_6]] : !fir.ref>>> +// CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_10]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_15:.*]] = fir.embox %[[VAL_9]]#1(%[[VAL_14]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +// CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_6]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_7]]#1 : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_15]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_4]] : (index) -> i32 +// CHECK: %[[VAL_22:.*]] = fir.call @_FortranACshift(%[[VAL_17]], %[[VAL_18]], %[[VAL_19]], %[[VAL_20]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.box, i32, !fir.ref, i32) -> none + +// 2d array expr shift by array expr +func.func @cshift5(%arg0: !hlfir.expr {fir.bindc_name = "a"}, %arg1: !hlfir.expr {fir.bindc_name = "sh"}) { + %2 = hlfir.cshift %arg0 %arg1 : (!hlfir.expr, !hlfir.expr) -> !hlfir.expr + hlfir.destroy %2 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @cshift5( +// CHECK-SAME: %[[VAL_0:.*]]: !hlfir.expr {fir.bindc_name = "a"}, +// CHECK-SAME: %[[VAL_1:.*]]: !hlfir.expr {fir.bindc_name = "sh"}) { +// CHECK: %[[VAL_2:.*]] = arith.constant true +// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_5:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_6:.*]] = fir.alloca !fir.box>> +// CHECK: %[[VAL_7:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<2> +// CHECK: %[[VAL_8:.*]]:3 = hlfir.associate %[[VAL_0]](%[[VAL_7]]) {adapt.valuebyref} : (!hlfir.expr, !fir.shape<2>) -> (!fir.box>, !fir.ref>, i1) +// CHECK: %[[VAL_9:.*]] = hlfir.get_extent %[[VAL_7]] {dim = 0 : index} : (!fir.shape<2>) -> index +// CHECK: %[[VAL_10:.*]] = hlfir.get_extent %[[VAL_7]] {dim = 1 : index} : (!fir.shape<2>) -> index +// CHECK: %[[VAL_11:.*]] = hlfir.shape_of %[[VAL_1]] : (!hlfir.expr) -> !fir.shape<1> +// CHECK: %[[VAL_12:.*]]:3 = hlfir.associate %[[VAL_1]](%[[VAL_11]]) {adapt.valuebyref} : (!hlfir.expr, !fir.shape<1>) -> (!fir.box>, !fir.ref>, i1) +// CHECK: %[[VAL_13:.*]] = hlfir.get_extent %[[VAL_11]] {dim = 0 : index} : (!fir.shape<1>) -> index +// CHECK: %[[VAL_14:.*]] = fir.shape %[[VAL_9]], %[[VAL_10]] : (index, index) -> !fir.shape<2> +// CHECK: %[[VAL_15:.*]] = fir.embox %[[VAL_8]]#1(%[[VAL_14]]) : (!fir.ref>, !fir.shape<2>) -> !fir.box> +// CHECK: %[[VAL_16:.*]] = fir.zero_bits !fir.heap> +// CHECK: %[[VAL_17:.*]] = fir.shape %[[VAL_5]], %[[VAL_5]] : (index, index) -> !fir.shape<2> +// CHECK: %[[VAL_18:.*]] = fir.embox %[[VAL_16]](%[[VAL_17]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> +// CHECK: fir.store %[[VAL_18]] to %[[VAL_6]] : !fir.ref>>> +// CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_13]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_12]]#1(%[[VAL_19]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_6]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_15]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_20]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_4]] : (index) -> i32 +// CHECK: %[[VAL_27:.*]] = fir.call @_FortranACshift(%[[VAL_22]], %[[VAL_23]], %[[VAL_24]], %[[VAL_25]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.box, i32, !fir.ref, i32) -> none + +// 2d array expr shift by array expr with explicit dim +func.func @cshift6(%arg0: !hlfir.expr {fir.bindc_name = "a"}, %arg1: !hlfir.expr {fir.bindc_name = "sh"}, %dim : i16) { + %2 = hlfir.cshift %arg0 %arg1 dim %dim : (!hlfir.expr, !hlfir.expr, i16) -> !hlfir.expr + hlfir.destroy %2 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @cshift6( +// CHECK-SAME: %[[VAL_0:.*]]: !hlfir.expr {fir.bindc_name = "a"}, +// CHECK-SAME: %[[VAL_1:.*]]: !hlfir.expr {fir.bindc_name = "sh"}, +// CHECK-SAME: %[[VAL_2:.*]]: i16) { +// CHECK: %[[VAL_3:.*]] = arith.constant true +// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_6:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_7:.*]] = fir.alloca !fir.box>> +// CHECK: %[[VAL_8:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<2> +// CHECK: %[[VAL_9:.*]]:3 = hlfir.associate %[[VAL_0]](%[[VAL_8]]) {adapt.valuebyref} : (!hlfir.expr, !fir.shape<2>) -> (!fir.box>, !fir.ref>, i1) +// CHECK: %[[VAL_10:.*]] = hlfir.get_extent %[[VAL_8]] {dim = 0 : index} : (!fir.shape<2>) -> index +// CHECK: %[[VAL_11:.*]] = hlfir.get_extent %[[VAL_8]] {dim = 1 : index} : (!fir.shape<2>) -> index +// CHECK: %[[VAL_12:.*]] = hlfir.shape_of %[[VAL_1]] : (!hlfir.expr) -> !fir.shape<1> +// CHECK: %[[VAL_13:.*]]:3 = hlfir.associate %[[VAL_1]](%[[VAL_12]]) {adapt.valuebyref} : (!hlfir.expr, !fir.shape<1>) -> (!fir.box>, !fir.ref>, i1) +// CHECK: %[[VAL_14:.*]] = hlfir.get_extent %[[VAL_12]] {dim = 0 : index} : (!fir.shape<1>) -> index +// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_2]] : (i16) -> i32 +// CHECK: %[[VAL_16:.*]] = fir.shape %[[VAL_10]], %[[VAL_11]] : (index, index) -> !fir.shape<2> +// CHECK: %[[VAL_17:.*]] = fir.embox %[[VAL_9]]#1(%[[VAL_16]]) : (!fir.ref>, !fir.shape<2>) -> !fir.box> +// CHECK: %[[VAL_18:.*]] = fir.zero_bits !fir.heap> +// CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_6]], %[[VAL_6]] : (index, index) -> !fir.shape<2> +// CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_18]](%[[VAL_19]]) : (!fir.heap>, !fir.shape<2>) -> !fir.box>> +// CHECK: fir.store %[[VAL_20]] to %[[VAL_7]] : !fir.ref>>> +// CHECK: %[[VAL_21:.*]] = fir.shape %[[VAL_14]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_22:.*]] = fir.embox %[[VAL_13]]#1(%[[VAL_21]]) : (!fir.ref>, !fir.shape<1>) -> !fir.box> +// CHECK: %[[VAL_24:.*]] = fir.convert %[[VAL_7]] : (!fir.ref>>>) -> !fir.ref> +// CHECK: %[[VAL_25:.*]] = fir.convert %[[VAL_17]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_22]] : (!fir.box>) -> !fir.box +// CHECK: %[[VAL_28:.*]] = fir.call @_FortranACshift(%[[VAL_24]], %[[VAL_25]], %[[VAL_26]], %[[VAL_15]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, !fir.box, i32, !fir.ref, i32) -> none + +// shift of polymorphic array +func.func @cshift7(%arg0: !fir.ref>>>>, %arg1: !fir.ref) { + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {fortran_attrs = #fir.var_attrs, uniq_name = "a"} : (!fir.ref>>>>, !fir.dscope) -> (!fir.ref>>>>, !fir.ref>>>>) + %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "sh"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %c2_i32 = arith.constant 2 : i32 + %3 = fir.load %1#0 : !fir.ref>>>> + %4 = hlfir.cshift %3 %c2_i32 : (!fir.class>>>, i32) -> !hlfir.expr?> + hlfir.assign %4 to %1#0 realloc : !hlfir.expr?>, !fir.ref>>>> + hlfir.destroy %4 : !hlfir.expr?> + return +} +// CHECK-LABEL: func.func @cshift7( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>>, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref) { +// CHECK: %[[VAL_2:.*]] = arith.constant true +// CHECK: %[[VAL_4:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32 +// CHECK: %[[VAL_6:.*]] = fir.alloca !fir.class>>> +// CHECK: %[[VAL_7:.*]] = fir.alloca i32 +// CHECK: %[[VAL_8:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_8]] {fortran_attrs = #fir.var_attrs, uniq_name = "a"} : (!fir.ref>>>>, !fir.dscope) -> (!fir.ref>>>>, !fir.ref>>>>) +// CHECK: %[[VAL_10:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %[[VAL_8]] {uniq_name = "sh"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_9]]#0 : !fir.ref>>>> +// CHECK: fir.store %[[VAL_5]] to %[[VAL_7]] : !fir.ref +// CHECK: %[[VAL_12:.*]] = fir.zero_bits !fir.heap>> +// CHECK: %[[VAL_13:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_14:.*]] = fir.embox %[[VAL_12]](%[[VAL_13]]) source_box %[[VAL_11]] : (!fir.heap>>, !fir.shape<1>, !fir.class>>>) -> !fir.class>>> +// CHECK: fir.store %[[VAL_14]] to %[[VAL_6]] : !fir.ref>>>> +// CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_7]] : !fir.ref +// CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_6]] : (!fir.ref>>>>) -> !fir.ref> +// CHECK: %[[VAL_18:.*]] = fir.convert %[[VAL_11]] : (!fir.class>>>) -> !fir.box +// CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_15]] : (i32) -> i64 +// CHECK: %[[VAL_21:.*]] = fir.call @_FortranACshiftVector(%[[VAL_17]], %[[VAL_18]], %[[VAL_19]], %{{.*}}, %{{.*}}) : (!fir.ref>, !fir.box, i64, !fir.ref, i32) -> none diff --git a/flang/test/HLFIR/element-codegen-issue-118922.fir b/flang/test/HLFIR/element-codegen-issue-118922.fir new file mode 100644 index 0000000000000..8fc0aa92a6b35 --- /dev/null +++ b/flang/test/HLFIR/element-codegen-issue-118922.fir @@ -0,0 +1,48 @@ +// Test issue 113843 and 118922 fix: do not elide hlfir.elemental final as_expr +// copy if this is not the last operation. +// RUN: fir-opt %s --bufferize-hlfir | FileCheck %s + +func.func @_QMmPbug(%val: !fir.char<1>, %var: !fir.ref>>) { + %c1 = arith.constant 1 : index + %c10 = arith.constant 10 : index + %1 = fir.shape %c10 : (index) -> !fir.shape<1> + %expr = hlfir.elemental %1 typeparams %c1 unordered : (!fir.shape<1>, index) -> !hlfir.expr<10x!fir.char<1>> { + ^bb0(%arg2: index): + %alloc = fir.allocmem !fir.char<1> + fir.store %val to %alloc : !fir.heap> + %addr = fir.convert %alloc: (!fir.heap>) -> !fir.ref> + %9 = hlfir.as_expr %addr : (!fir.ref>) -> !hlfir.expr> + fir.freemem %alloc : !fir.heap> + hlfir.yield_element %9 : !hlfir.expr> + } + hlfir.assign %expr to %var : !hlfir.expr<10x!fir.char<1>>, !fir.ref>> + hlfir.destroy %expr : !hlfir.expr<10x!fir.char<1>> + return +} + +// CHECK-LABEL: func.func @_QMmPbug( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.char<1>, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref>>) { +// CHECK: %[[VAL_2:.*]] = fir.alloca !fir.char<1> {bindc_name = ".tmp"} +// CHECK: %[[VAL_3:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_4:.*]] = arith.constant 10 : index +// CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_6:.*]] = fir.allocmem !fir.array<10x!fir.char<1>> {bindc_name = ".tmp.array", uniq_name = ""} +// CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_6]](%[[VAL_5]]) typeparams %[[VAL_3]] {uniq_name = ".tmp.array"} : (!fir.heap>>, !fir.shape<1>, index) -> (!fir.heap>>, !fir.heap>>) +// CHECK: %[[VAL_8:.*]] = arith.constant true +// CHECK: %[[VAL_9:.*]] = arith.constant 1 : index +// CHECK: fir.do_loop %[[VAL_10:.*]] = %[[VAL_9]] to %[[VAL_4]] step %[[VAL_9]] unordered { +// CHECK: %[[VAL_11:.*]] = fir.allocmem !fir.char<1> +// CHECK: fir.store %[[VAL_0]] to %[[VAL_11]] : !fir.heap> +// CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (!fir.heap>) -> !fir.ref> +// CHECK: %[[VAL_13:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_14:.*]] = arith.constant false +// CHECK: %[[VAL_15:.*]]:2 = hlfir.declare %[[VAL_2]] typeparams %[[VAL_13]] {uniq_name = ".tmp"} : (!fir.ref>, index) -> (!fir.ref>, !fir.ref>) +// CHECK: hlfir.assign %[[VAL_12]] to %[[VAL_15]]#0 temporary_lhs : !fir.ref>, !fir.ref> +// CHECK: %[[VAL_16:.*]] = fir.undefined tuple>, i1> +// CHECK: %[[VAL_17:.*]] = fir.insert_value %[[VAL_16]], %[[VAL_14]], [1 : index] : (tuple>, i1>, i1) -> tuple>, i1> +// CHECK: %[[VAL_18:.*]] = fir.insert_value %[[VAL_17]], %[[VAL_15]]#0, [0 : index] : (tuple>, i1>, !fir.ref>) -> tuple>, i1> +// CHECK: fir.freemem %[[VAL_11]] : !fir.heap> +// CHECK: %[[VAL_19:.*]] = hlfir.designate %[[VAL_7]]#0 (%[[VAL_10]]) typeparams %[[VAL_3]] : (!fir.heap>>, index, index) -> !fir.ref> +// CHECK: hlfir.assign %[[VAL_15]]#0 to %[[VAL_19]] temporary_lhs : !fir.ref>, !fir.ref> +// CHECK: } diff --git a/flang/test/HLFIR/elemental-codegen.fir b/flang/test/HLFIR/elemental-codegen.fir index 3c33bf8fca2d1..0d5f343cb1771 100644 --- a/flang/test/HLFIR/elemental-codegen.fir +++ b/flang/test/HLFIR/elemental-codegen.fir @@ -192,7 +192,7 @@ func.func @test_polymorphic(%arg0: !fir.class> {fir.bindc_ // CHECK: %[[VAL_35:.*]] = fir.absent !fir.box // CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_4]] : (!fir.ref>>>>) -> !fir.ref> // CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_31]] : (!fir.ref>) -> !fir.ref -// CHECK: %[[VAL_38:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_36]], %{{.*}}, %[[VAL_34]], %[[VAL_35]], %[[VAL_37]], %[[VAL_33]]) : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_38:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_36]], %[[VAL_34]], %[[VAL_35]], %[[VAL_37]], %[[VAL_33]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 // CHECK: %[[VAL_39:.*]] = fir.load %[[VAL_13]]#0 : !fir.ref>>>> // CHECK: %[[VAL_40:.*]] = arith.constant 1 : index // CHECK: fir.do_loop %[[VAL_41:.*]] = %[[VAL_40]] to %[[EX1]] step %[[VAL_40]] unordered { @@ -276,7 +276,7 @@ func.func @test_polymorphic_expr(%arg0: !fir.class> {fir.b // CHECK: %[[VAL_36:.*]] = fir.absent !fir.box // CHECK: %[[VAL_37:.*]] = fir.convert %[[VAL_5]] : (!fir.ref>>>>) -> !fir.ref> // CHECK: %[[VAL_38:.*]] = fir.convert %[[VAL_32]] : (!fir.ref>) -> !fir.ref -// CHECK: %[[VAL_39:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_37]], %{{.*}}, %[[VAL_35]], %[[VAL_36]], %[[VAL_38]], %[[VAL_34]]) : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_39:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_37]], %[[VAL_35]], %[[VAL_36]], %[[VAL_38]], %[[VAL_34]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 // CHECK: %[[VAL_40:.*]] = fir.load %[[VAL_14]]#0 : !fir.ref>>>> // CHECK: %[[VAL_41:.*]] = arith.constant 1 : index // CHECK: fir.do_loop %[[VAL_42:.*]] = %[[VAL_41]] to %[[VAL_3]] step %[[VAL_41]] unordered { @@ -329,7 +329,7 @@ func.func @test_polymorphic_expr(%arg0: !fir.class> {fir.b // CHECK: %[[VAL_85:.*]] = fir.absent !fir.box // CHECK: %[[VAL_86:.*]] = fir.convert %[[VAL_4]] : (!fir.ref>>>>) -> !fir.ref> // CHECK: %[[VAL_87:.*]] = fir.convert %[[VAL_81]] : (!fir.ref>) -> !fir.ref -// CHECK: %[[VAL_88:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_86]], %{{.*}}, %[[VAL_84]], %[[VAL_85]], %[[VAL_87]], %[[VAL_83]]) : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +// CHECK: %[[VAL_88:.*]] = fir.call @_FortranAAllocatableAllocate(%[[VAL_86]], %[[VAL_84]], %[[VAL_85]], %[[VAL_87]], %[[VAL_83]]) : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 // CHECK: %[[VAL_89:.*]] = fir.load %[[VAL_63]]#0 : !fir.ref>>>> // CHECK: %[[VAL_90:.*]] = arith.constant 1 : index // CHECK: fir.do_loop %[[VAL_91:.*]] = %[[VAL_90]] to %[[VAL_3]] step %[[VAL_90]] unordered { diff --git a/flang/test/HLFIR/invalid.fir b/flang/test/HLFIR/invalid.fir index 5c5db7aac0697..b35bec4b2a899 100644 --- a/flang/test/HLFIR/invalid.fir +++ b/flang/test/HLFIR/invalid.fir @@ -1348,3 +1348,78 @@ func.func @bad_eval_in_mem_3() { } return } + +// ----- + +func.func @bad_cshift1(%arg0: !hlfir.expr, %arg1: i32) { + // expected-error@+1 {{'hlfir.cshift' op input and output arrays should have the same element type}} + %0 = hlfir.cshift %arg0 %arg1 : (!hlfir.expr, i32) -> !hlfir.expr + return +} + +// ----- + +func.func @bad_cshift2(%arg0: !hlfir.expr, %arg1: i32) { + // expected-error@+1 {{'hlfir.cshift' op input and output arrays should have the same rank}} + %0 = hlfir.cshift %arg0 %arg1 : (!hlfir.expr, i32) -> !hlfir.expr + return +} + +// ----- + +func.func @bad_cshift3(%arg0: !hlfir.expr<2x2xi32>, %arg1: i32) { + // expected-error@+1 {{'hlfir.cshift' op output array's shape conflicts with the input array's shape}} + %0 = hlfir.cshift %arg0 %arg1 : (!hlfir.expr<2x2xi32>, i32) -> !hlfir.expr<2x3xi32> + return +} + +// ----- + +func.func @bad_cshift4(%arg0: !hlfir.expr<2x2xi32>, %arg1: i32) { + %c0 = arith.constant 0 : index + // expected-error@+1 {{'hlfir.cshift' op DIM must be >= 1}} + %0 = hlfir.cshift %arg0 %arg1 dim %c0 : (!hlfir.expr<2x2xi32>, i32, index) -> !hlfir.expr<2x2xi32> + return +} + +// ----- + +func.func @bad_cshift5(%arg0: !hlfir.expr<2x2xi32>, %arg1: i32) { + %c10 = arith.constant 10 : index + // expected-error@+1 {{'hlfir.cshift' op DIM must be <= input array's rank}} + %0 = hlfir.cshift %arg0 %arg1 dim %c10 : (!hlfir.expr<2x2xi32>, i32, index) -> !hlfir.expr<2x2xi32> + return +} + +// ----- + +func.func @bad_cshift6(%arg0: !hlfir.expr<2x2xi32>, %arg1: !hlfir.expr<2x2xi32>) { + // expected-error@+1 {{'hlfir.cshift' op SHIFT's rank must be 1 less than the input array's rank}} + %0 = hlfir.cshift %arg0 %arg1 : (!hlfir.expr<2x2xi32>, !hlfir.expr<2x2xi32>) -> !hlfir.expr<2x2xi32> + return +} + +// ----- + +func.func @bad_cshift7(%arg0: !hlfir.expr, %arg1: !hlfir.expr<3xi32>) { + %c1 = arith.constant 1 : index + // expected-error@+1 {{'hlfir.cshift' op SHAPE(ARRAY)(2) must be equal to SHAPE(SHIFT)(1): 2 != 3}} + %0 = hlfir.cshift %arg0 %arg1 dim %c1 : (!hlfir.expr, !hlfir.expr<3xi32>, index) -> !hlfir.expr<2x2xi32> + return +} + +// ----- + +func.func @bad_cshift8(%arg0: !hlfir.expr>, %arg1: i32) { + // expected-error@+1 {{'hlfir.cshift' op kind mismatch between input and output arrays}} + %0 = hlfir.cshift %arg0 %arg1 : (!hlfir.expr>, i32) -> !hlfir.expr> + return +} + +// ----- + +func.func @bad_cshift9(%arg0: !hlfir.expr>, %arg1: i32) { + // expected-error@+1 {{'hlfir.cshift' op character LEN mismatch between input and output arrays}} + %0 = hlfir.cshift %arg0 %arg1 : (!hlfir.expr>, i32) -> !hlfir.expr> + return +} diff --git a/flang/test/HLFIR/minloc-elemental.fir b/flang/test/HLFIR/minloc-elemental.fir index 45993c5eee0c9..5fa482a7b904e 100644 --- a/flang/test/HLFIR/minloc-elemental.fir +++ b/flang/test/HLFIR/minloc-elemental.fir @@ -188,67 +188,65 @@ func.func @_QPtest_kind2_convert(%arg0: !fir.box> {fir.bindc_n hlfir.destroy %6 : !hlfir.expr> return } -// The minloc has other uses, not an assign that gets optimized out. -// CHECK-LABEL: _QPtest_kind2_convert -// CHECK-SAME: (%arg0: !fir.box> {fir.bindc_name = "array"}, %arg1: !fir.ref {fir.bindc_name = "val"}, %arg2: !fir.box> {fir.bindc_name = "m"}) { -// CHECK-NEXT: %false = arith.constant false -// CHECK-NEXT: %true = arith.constant true -// CHECK-NEXT: %c2147483647_i32 = arith.constant 2147483647 : i32 -// CHECK-NEXT: %c1_i16 = arith.constant 1 : i16 -// CHECK-NEXT: %c0 = arith.constant 0 : index -// CHECK-NEXT: %c0_i16 = arith.constant 0 : i16 -// CHECK-NEXT: %c1 = arith.constant 1 : index -// CHECK-NEXT: %[[V0:.*]] = fir.alloca i16 -// CHECK-NEXT: %[[V1:.*]] = fir.alloca !fir.array<1xi16> -// CHECK-NEXT: %[[V2:.*]]:2 = hlfir.declare %arg0 {uniq_name = "_QFtestEarray"} : (!fir.box>) -> (!fir.box>, !fir.box>) -// CHECK-NEXT: %[[V3:.*]]:2 = hlfir.declare %arg2 {uniq_name = "_QFtestEm"} : (!fir.box>) -> (!fir.box>, !fir.box>) -// CHECK-NEXT: %[[V4:.*]]:2 = hlfir.declare %arg1 {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) -// CHECK-NEXT: %[[V5:.*]] = fir.load %[[V4]]#0 : !fir.ref -// CHECK-NEXT: %[[V6:.*]] = hlfir.designate %[[V1]] (%c1) : (!fir.ref>, index) -> !fir.ref -// CHECK-NEXT: fir.store %c0_i16 to %[[V6]] : !fir.ref -// CHECK-NEXT: fir.store %c0_i16 to %[[V0]] : !fir.ref -// CHECK-NEXT: %[[V7:.*]]:3 = fir.box_dims %[[V2]]#0, %c0 : (!fir.box>, index) -> (index, index, index) -// CHECK-NEXT: %[[V8:.*]] = arith.subi %[[V7]]#1, %c1 : index -// CHECK-NEXT: %[[V9:.*]] = fir.do_loop %arg3 = %c0 to %[[V8]] step %c1 iter_args(%arg4 = %c2147483647_i32) -> (i32) { -// CHECK-NEXT: %[[V15:.*]] = arith.addi %arg3, %c1 : index -// CHECK-NEXT: %[[V16:.*]] = hlfir.designate %[[V2]]#0 (%[[V15]]) : (!fir.box>, index) -> !fir.ref -// CHECK-NEXT: %[[V17:.*]] = fir.load %[[V16]] : !fir.ref -// CHECK-NEXT: %[[V18:.*]] = arith.cmpi sge, %[[V17]], %[[V5]] : i32 -// CHECK-NEXT: %[[V19:.*]] = fir.if %[[V18]] -> (i32) { -// CHECK-NEXT: %[[ISFIRST:.*]] = fir.load %[[V0]] : !fir.ref -// CHECK-NEXT: %[[V23:.*]] = hlfir.designate %[[V2]]#0 (%[[V15]]) : (!fir.box>, index) -> !fir.ref -// CHECK-NEXT: %[[V24:.*]] = fir.load %[[V23]] : !fir.ref -// CHECK-NEXT: %[[V25:.*]] = arith.cmpi slt, %[[V24]], %arg4 : i32 -// CHECK-NEXT: %[[ISFIRSTL:.*]] = fir.convert %[[ISFIRST]] : (i16) -> i1 -// CHECK-NEXT: %[[ISFIRSTNOT:.*]] = arith.xori %[[ISFIRSTL]], %true : i1 -// CHECK-NEXT: %[[ORCOND:.*]] = arith.ori %[[V25]], %[[ISFIRSTNOT]] : i1 -// CHECK-NEXT: %[[V26:.*]] = fir.if %[[ORCOND]] -> (i32) { -// CHECK-NEXT: fir.store %c1_i16 to %[[V0]] : !fir.ref -// CHECK-NEXT: %[[V27:.*]] = hlfir.designate %[[V1]] (%c1) : (!fir.ref>, index) -> !fir.ref -// CHECK-NEXT: %[[V28:.*]] = fir.convert %[[V15]] : (index) -> i16 -// CHECK-NEXT: fir.store %[[V28]] to %[[V27]] : !fir.ref -// CHECK-NEXT: fir.result %[[V24]] : i32 -// CHECK-NEXT: } else { -// CHECK-NEXT: fir.result %arg4 : i32 -// CHECK-NEXT: } -// CHECK-NEXT: fir.result %[[V26]] : i32 -// CHECK-NEXT: } else { -// CHECK-NEXT: fir.result %arg4 : i32 -// CHECK-NEXT: } -// CHECK-NEXT: fir.result %[[V19]] : i32 -// CHECK-NEXT: } -// CHECK-NEXT: %[[V12:.*]] = hlfir.as_expr %[[V1]] move %false : (!fir.ref>, i1) -> !hlfir.expr<1xi16> -// CHECK-NEXT: %[[V13:.*]] = fir.shape %c1 : (index) -> !fir.shape<1> -// CHECK-NEXT: %[[V14:.*]] = hlfir.elemental %[[V13]] unordered : (!fir.shape<1>) -> !hlfir.expr { -// CHECK-NEXT: ^bb0(%arg3: index): -// CHECK-NEXT: %[[V15:.*]] = hlfir.apply %[[V12]], %arg3 : (!hlfir.expr<1xi16>, index) -> i16 -// CHECK-NEXT: %[[V16:.*]] = fir.convert %[[V15]] : (i16) -> i32 -// CHECK-NEXT: hlfir.yield_element %[[V16]] : i32 -// CHECK-NEXT: } -// CHECK-NEXT: hlfir.assign %[[V14]] to %[[V3]]#0 : !hlfir.expr, !fir.box> -// CHECK-NEXT: hlfir.destroy %[[V14]] : !hlfir.expr -// CHECK-NEXT: return - +// CHECK-LABEL: func.func @_QPtest_kind2_convert( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "array"}, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref {fir.bindc_name = "val"}, +// CHECK-SAME: %[[VAL_2:.*]]: !fir.box> {fir.bindc_name = "m"}) { +// CHECK: %[[VAL_3:.*]] = arith.constant false +// CHECK: %[[VAL_4:.*]] = arith.constant true +// CHECK: %[[VAL_5:.*]] = arith.constant 2147483647 : i32 +// CHECK: %[[VAL_6:.*]] = arith.constant 1 : i16 +// CHECK: %[[VAL_7:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_8:.*]] = arith.constant 0 : i16 +// CHECK: %[[VAL_9:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_10:.*]] = fir.alloca i16 +// CHECK: %[[VAL_11:.*]] = fir.alloca !fir.array<1xi16> +// CHECK: %[[VAL_12:.*]]:2 = hlfir.declare %[[VAL_0]] {uniq_name = "_QFtestEarray"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK: %[[VAL_13:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "_QFtestEm"} : (!fir.box>) -> (!fir.box>, !fir.box>) +// CHECK: %[[VAL_14:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFtestEval"} : (!fir.ref) -> (!fir.ref, !fir.ref) +// CHECK: %[[VAL_15:.*]] = fir.load %[[VAL_14]]#0 : !fir.ref +// CHECK: %[[VAL_16:.*]] = hlfir.designate %[[VAL_11]] (%[[VAL_9]]) : (!fir.ref>, index) -> !fir.ref +// CHECK: fir.store %[[VAL_8]] to %[[VAL_16]] : !fir.ref +// CHECK: fir.store %[[VAL_8]] to %[[VAL_10]] : !fir.ref +// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_12]]#0, %[[VAL_7]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_18:.*]] = arith.subi %[[VAL_17]]#1, %[[VAL_9]] : index +// CHECK: %[[VAL_19:.*]] = fir.do_loop %[[VAL_20:.*]] = %[[VAL_7]] to %[[VAL_18]] step %[[VAL_9]] iter_args(%[[VAL_21:.*]] = %[[VAL_5]]) -> (i32) { +// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_20]], %[[VAL_9]] : index +// CHECK: %[[VAL_23:.*]] = hlfir.designate %[[VAL_12]]#0 (%[[VAL_22]]) : (!fir.box>, index) -> !fir.ref +// CHECK: %[[VAL_24:.*]] = fir.load %[[VAL_23]] : !fir.ref +// CHECK: %[[VAL_25:.*]] = arith.cmpi sge, %[[VAL_24]], %[[VAL_15]] : i32 +// CHECK: %[[VAL_26:.*]] = fir.if %[[VAL_25]] -> (i32) { +// CHECK: %[[VAL_27:.*]] = fir.load %[[VAL_10]] : !fir.ref +// CHECK: %[[VAL_28:.*]] = hlfir.designate %[[VAL_12]]#0 (%[[VAL_22]]) : (!fir.box>, index) -> !fir.ref +// CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_28]] : !fir.ref +// CHECK: %[[VAL_30:.*]] = arith.cmpi slt, %[[VAL_29]], %[[VAL_21]] : i32 +// CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_27]] : (i16) -> i1 +// CHECK: %[[VAL_32:.*]] = arith.xori %[[VAL_31]], %[[VAL_4]] : i1 +// CHECK: %[[VAL_33:.*]] = arith.ori %[[VAL_30]], %[[VAL_32]] : i1 +// CHECK: %[[VAL_34:.*]] = fir.if %[[VAL_33]] -> (i32) { +// CHECK: fir.store %[[VAL_6]] to %[[VAL_10]] : !fir.ref +// CHECK: %[[VAL_35:.*]] = hlfir.designate %[[VAL_11]] (%[[VAL_9]]) : (!fir.ref>, index) -> !fir.ref +// CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_22]] : (index) -> i16 +// CHECK: fir.store %[[VAL_36]] to %[[VAL_35]] : !fir.ref +// CHECK: fir.result %[[VAL_29]] : i32 +// CHECK: } else { +// CHECK: fir.result %[[VAL_21]] : i32 +// CHECK: } +// CHECK: fir.result %[[VAL_34]] : i32 +// CHECK: } else { +// CHECK: fir.result %[[VAL_21]] : i32 +// CHECK: } +// CHECK: fir.result %[[VAL_26]] : i32 +// CHECK: } +// CHECK: %[[VAL_37:.*]] = hlfir.as_expr %[[VAL_11]] move %[[VAL_3]] : (!fir.ref>, i1) -> !hlfir.expr<1xi16> +// CHECK: fir.do_loop %[[VAL_38:.*]] = %[[VAL_9]] to %[[VAL_9]] step %[[VAL_9]] unordered { +// CHECK: %[[VAL_39:.*]] = hlfir.apply %[[VAL_37]], %[[VAL_38]] : (!hlfir.expr<1xi16>, index) -> i16 +// CHECK: %[[VAL_40:.*]] = fir.convert %[[VAL_39]] : (i16) -> i32 +// CHECK: %[[VAL_41:.*]] = hlfir.designate %[[VAL_13]]#0 (%[[VAL_38]]) : (!fir.box>, index) -> !fir.ref +// CHECK: hlfir.assign %[[VAL_40]] to %[[VAL_41]] : i32, !fir.ref +// CHECK: } +// CHECK: return +// CHECK: } func.func @_QPtest_float(%arg0: !fir.box> {fir.bindc_name = "array"}, %arg1: !fir.ref {fir.bindc_name = "val"}, %arg2: !fir.box> {fir.bindc_name = "m"}) { diff --git a/flang/test/HLFIR/opt-array-slice-assign.fir b/flang/test/HLFIR/opt-array-slice-assign.fir index 11bd97c115834..3db47b1da8cd3 100644 --- a/flang/test/HLFIR/opt-array-slice-assign.fir +++ b/flang/test/HLFIR/opt-array-slice-assign.fir @@ -382,3 +382,427 @@ func.func @_QPtest6(%arg0: !fir.ref> {fir.bindc_name = "x"}, } // CHECK-LABEL: func.func @_QPtest6( // CHECK-NOT: hlfir.elemental + +// Check that 'x(9,:)=SUM(x(1:8,:),DIM=1)' is optimized +// due to the LHS and RHS being disjoint array sections. +func.func @test_disjoint_triple_index(%arg0: !fir.box> {fir.bindc_name = "x"}) { + %cst = arith.constant 0.000000e+00 : f32 + %c9 = arith.constant 9 : index + %c0 = arith.constant 0 : index + %c8 = arith.constant 8 : index + %c1 = arith.constant 1 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %2:3 = fir.box_dims %1#1, %c1 : (!fir.box>, index) -> (index, index, index) + %3 = arith.cmpi sgt, %2#1, %c0 : index + %4 = arith.select %3, %2#1, %c0 : index + %5 = fir.shape %c8, %4 : (index, index) -> !fir.shape<2> + %6 = hlfir.designate %1#0 (%c1:%c8:%c1, %c1:%2#1:%c1) shape %5 : (!fir.box>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box> + %7 = fir.shape %4 : (index) -> !fir.shape<1> + %8 = hlfir.elemental %7 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg1: index): + %10 = fir.alloca f32 {bindc_name = ".sum.reduction"} + fir.store %cst to %10 : !fir.ref + fir.do_loop %arg2 = %c1 to %c8 step %c1 unordered { + %12 = fir.load %10 : !fir.ref + %13 = hlfir.designate %6 (%arg2, %arg1) : (!fir.box>, index, index) -> !fir.ref + %14 = fir.load %13 : !fir.ref + %15 = arith.addf %12, %14 fastmath : f32 + fir.store %15 to %10 : !fir.ref + } + %11 = fir.load %10 : !fir.ref + hlfir.yield_element %11 : f32 + } + %9 = hlfir.designate %1#0 (%c9, %c1:%2#1:%c1) shape %7 : (!fir.box>, index, index, index, index, !fir.shape<1>) -> !fir.box> + hlfir.assign %8 to %9 : !hlfir.expr, !fir.box> + hlfir.destroy %8 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @test_disjoint_triple_index( +// CHECK-NOT: hlfir.elemental + +// Check that 'x(9,:)=SUM(x(9:9,:),DIM=1)' is not optimized. +func.func @test_overlapping_triple_index(%arg0: !fir.box> {fir.bindc_name = "x"}) { + %cst = arith.constant 0.000000e+00 : f32 + %c9 = arith.constant 9 : index + %c0 = arith.constant 0 : index + %c8 = arith.constant 8 : index + %c1 = arith.constant 1 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %2:3 = fir.box_dims %1#1, %c1 : (!fir.box>, index) -> (index, index, index) + %3 = arith.cmpi sgt, %2#1, %c0 : index + %4 = arith.select %3, %2#1, %c0 : index + %5 = fir.shape %c8, %4 : (index, index) -> !fir.shape<2> + %6 = hlfir.designate %1#0 (%c9:%c9:%c1, %c1:%2#1:%c1) shape %5 : (!fir.box>, index, index, index, index, index, index, !fir.shape<2>) -> !fir.box> + %7 = fir.shape %4 : (index) -> !fir.shape<1> + %8 = hlfir.elemental %7 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg1: index): + %10 = fir.alloca f32 {bindc_name = ".sum.reduction"} + fir.store %cst to %10 : !fir.ref + fir.do_loop %arg2 = %c1 to %c8 step %c1 unordered { + %12 = fir.load %10 : !fir.ref + %13 = hlfir.designate %6 (%arg2, %arg1) : (!fir.box>, index, index) -> !fir.ref + %14 = fir.load %13 : !fir.ref + %15 = arith.addf %12, %14 fastmath : f32 + fir.store %15 to %10 : !fir.ref + } + %11 = fir.load %10 : !fir.ref + hlfir.yield_element %11 : f32 + } + %9 = hlfir.designate %1#0 (%c9, %c1:%2#1:%c1) shape %7 : (!fir.box>, index, index, index, index, !fir.shape<1>) -> !fir.box> + hlfir.assign %8 to %9 : !hlfir.expr, !fir.box> + hlfir.destroy %8 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @test_overlapping_triple_index( +// CHECK: hlfir.elemental + +// Check that 'x(9:ub) = x(lb:6) + 1' is optimized, +// even though the lb and ub are unknown. +func.func @test_disjoint_unknown_bounds(%arg0: !fir.box> {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "lb"}, %arg2: !fir.ref {fir.bindc_name = "ub"}) { + %c-8 = arith.constant -8 : index + %c7 = arith.constant 7 : index + %c9 = arith.constant 9 : index + %cst = arith.constant 1.000000e+00 : f32 + %c0 = arith.constant 0 : index + %c1 = arith.constant 1 : index + %c6 = arith.constant 6 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestElb"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %2:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestEub"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %3:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %4 = fir.load %1#0 : !fir.ref + %5 = fir.convert %4 : (i32) -> index + %6 = arith.subi %c7, %5 : index + %7 = arith.cmpi sgt, %6, %c0 : index + %8 = arith.select %7, %6, %c0 : index + %9 = fir.shape %8 : (index) -> !fir.shape<1> + %10 = hlfir.designate %3#0 (%5:%c6:%c1) shape %9 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + %11 = hlfir.elemental %9 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg3: index): + %19 = hlfir.designate %10 (%arg3) : (!fir.box>, index) -> !fir.ref + %20 = fir.load %19 : !fir.ref + %21 = arith.addf %20, %cst fastmath : f32 + hlfir.yield_element %21 : f32 + } + %12 = fir.load %2#0 : !fir.ref + %13 = fir.convert %12 : (i32) -> index + %14 = arith.addi %13, %c-8 : index + %15 = arith.cmpi sgt, %14, %c0 : index + %16 = arith.select %15, %14, %c0 : index + %17 = fir.shape %16 : (index) -> !fir.shape<1> + %18 = hlfir.designate %3#0 (%c9:%13:%c1) shape %17 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + hlfir.assign %11 to %18 : !hlfir.expr, !fir.box> + hlfir.destroy %11 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @test_disjoint_unknown_bounds( +// CHECK-NOT: hlfir.elemental + +// Check that 'x(lb1:14) = x(lb2:15:-1) + 1' is optimized, +// even though lb1 and lb2 are unknown. +func.func @test_disjoint_unknown_bounds_negative_stride(%arg0: !fir.box> {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "lb1"}, %arg2: !fir.ref {fir.bindc_name = "lb2"}) { + %c1 = arith.constant 1 : index + %c14 = arith.constant 14 : index + %cst = arith.constant 1.000000e+00 : f32 + %c0 = arith.constant 0 : index + %c-1 = arith.constant -1 : index + %c15 = arith.constant 15 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestElb1"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %2:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestElb2"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %3:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %4 = fir.load %2#0 : !fir.ref + %5 = fir.convert %4 : (i32) -> index + %6 = arith.subi %c14, %5 : index + %7 = arith.divsi %6, %c-1 : index + %8 = arith.cmpi sgt, %7, %c0 : index + %9 = arith.select %8, %7, %c0 : index + %10 = fir.shape %9 : (index) -> !fir.shape<1> + %11 = hlfir.designate %3#0 (%5:%c15:%c-1) shape %10 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + %12 = hlfir.elemental %10 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg3: index): + %20 = hlfir.designate %11 (%arg3) : (!fir.box>, index) -> !fir.ref + %21 = fir.load %20 : !fir.ref + %22 = arith.addf %21, %cst fastmath : f32 + hlfir.yield_element %22 : f32 + } + %13 = fir.load %1#0 : !fir.ref + %14 = fir.convert %13 : (i32) -> index + %15 = arith.subi %c15, %14 : index + %16 = arith.cmpi sgt, %15, %c0 : index + %17 = arith.select %16, %15, %c0 : index + %18 = fir.shape %17 : (index) -> !fir.shape<1> + %19 = hlfir.designate %3#0 (%14:%c14:%c1) shape %18 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + hlfir.assign %12 to %19 : !hlfir.expr, !fir.box> + hlfir.destroy %12 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @test_disjoint_unknown_bounds_negative_stride( +// CHECK-NOT: hlfir.elemental + +// Check that 'x(1:5) = x(5:1:-1) + 1' is not optimized. +func.func @test_overlap_known_triplets_negative_stride(%arg0: !fir.box> {fir.bindc_name = "x"}) { + %cst = arith.constant 1.000000e+00 : f32 + %c-1 = arith.constant -1 : index + %c1 = arith.constant 1 : index + %c5 = arith.constant 5 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %2 = fir.shape %c5 : (index) -> !fir.shape<1> + %3 = hlfir.designate %1#0 (%c5:%c1:%c-1) shape %2 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + %4 = hlfir.elemental %2 unordered : (!fir.shape<1>) -> !hlfir.expr<5xf32> { + ^bb0(%arg1: index): + %6 = hlfir.designate %3 (%arg1) : (!fir.box>, index) -> !fir.ref + %7 = fir.load %6 : !fir.ref + %8 = arith.addf %7, %cst fastmath : f32 + hlfir.yield_element %8 : f32 + } + %5 = hlfir.designate %1#0 (%c1:%c5:%c1) shape %2 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + hlfir.assign %4 to %5 : !hlfir.expr<5xf32>, !fir.box> + hlfir.destroy %4 : !hlfir.expr<5xf32> + return +} +// CHECK-LABEL: func.func @test_overlap_known_triplets_negative_stride( +// CHECK: hlfir.elemental + +// Check that 'x(1:5) = x(6:ub:-1) + 1' is not optimized. +func.func @test_overlap_unknown_bound_negative_stride(%arg0: !fir.box> {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "ub"}) { + %c-7 = arith.constant -7 : index + %c5 = arith.constant 5 : index + %c1 = arith.constant 1 : index + %cst = arith.constant 1.000000e+00 : f32 + %c0 = arith.constant 0 : index + %c-1 = arith.constant -1 : index + %c6 = arith.constant 6 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEub"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %2:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %3 = fir.load %1#0 : !fir.ref + %4 = fir.convert %3 : (i32) -> index + %5 = arith.addi %4, %c-7 : index + %6 = arith.divsi %5, %c-1 : index + %7 = arith.cmpi sgt, %6, %c0 : index + %8 = arith.select %7, %6, %c0 : index + %9 = fir.shape %8 : (index) -> !fir.shape<1> + %10 = hlfir.designate %2#0 (%c6:%4:%c-1) shape %9 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + %11 = hlfir.elemental %9 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg2: index): + %14 = hlfir.designate %10 (%arg2) : (!fir.box>, index) -> !fir.ref + %15 = fir.load %14 : !fir.ref + %16 = arith.addf %15, %cst fastmath : f32 + hlfir.yield_element %16 : f32 + } + %12 = fir.shape %c5 : (index) -> !fir.shape<1> + %13 = hlfir.designate %2#0 (%c1:%c5:%c1) shape %12 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + hlfir.assign %11 to %13 : !hlfir.expr, !fir.box> + hlfir.destroy %11 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @test_overlap_unknown_bound_negative_stride( +// CHECK: hlfir.elemental + +// Check that 'x(1:5) = x(6:ub:stride) + 1' is not optimized. +func.func @test_overlap_unknown_bound_and_stride(%arg0: !fir.box> {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "ub"}, %arg2: !fir.ref {fir.bindc_name = "stride"}) { + %c5 = arith.constant 5 : index + %c1 = arith.constant 1 : index + %cst = arith.constant 1.000000e+00 : f32 + %c0 = arith.constant 0 : index + %c6 = arith.constant 6 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestEstride"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEub"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %3:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %4 = fir.load %2#0 : !fir.ref + %5 = fir.convert %4 : (i32) -> index + %6 = fir.load %1#0 : !fir.ref + %7 = fir.convert %6 : (i32) -> index + %8 = arith.subi %5, %c6 : index + %9 = arith.addi %8, %7 : index + %10 = arith.divsi %9, %7 : index + %11 = arith.cmpi sgt, %10, %c0 : index + %12 = arith.select %11, %10, %c0 : index + %13 = fir.shape %12 : (index) -> !fir.shape<1> + %14 = hlfir.designate %3#0 (%c6:%5:%7) shape %13 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + %15 = hlfir.elemental %13 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg3: index): + %18 = hlfir.designate %14 (%arg3) : (!fir.box>, index) -> !fir.ref + %19 = fir.load %18 : !fir.ref + %20 = arith.addf %19, %cst fastmath : f32 + hlfir.yield_element %20 : f32 + } + %16 = fir.shape %c5 : (index) -> !fir.shape<1> + %17 = hlfir.designate %3#0 (%c1:%c5:%c1) shape %16 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + hlfir.assign %15 to %17 : !hlfir.expr, !fir.box> + hlfir.destroy %15 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @test_overlap_unknown_bound_and_stride( +// CHECK: hlfir.elemental + +// Check that 'a(2:2:s1) = a(2:2:s2) + 1' is optimized, +// even though the strides are unknown. +func.func @test_identical_1element_unknown_strides(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "s1"}, %arg2: !fir.ref {fir.bindc_name = "s2"}) { + %c1_i32 = arith.constant 1 : i32 + %c0 = arith.constant 0 : index + %c2 = arith.constant 2 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEa"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEs1"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %3:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestEs2"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %4 = fir.load %3#0 : !fir.ref + %5 = fir.convert %4 : (i32) -> index + %6 = arith.divsi %5, %5 : index + %7 = arith.cmpi sgt, %6, %c0 : index + %8 = arith.select %7, %6, %c0 : index + %9 = fir.shape %8 : (index) -> !fir.shape<1> + %10 = hlfir.designate %1#0 (%c2:%c2:%5) shape %9 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + %11 = hlfir.elemental %9 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg3: index): + %19 = hlfir.designate %10 (%arg3) : (!fir.box>, index) -> !fir.ref + %20 = fir.load %19 : !fir.ref + %21 = arith.addi %20, %c1_i32 : i32 + hlfir.yield_element %21 : i32 + } + %12 = fir.load %2#0 : !fir.ref + %13 = fir.convert %12 : (i32) -> index + %14 = arith.divsi %13, %13 : index + %15 = arith.cmpi sgt, %14, %c0 : index + %16 = arith.select %15, %14, %c0 : index + %17 = fir.shape %16 : (index) -> !fir.shape<1> + %18 = hlfir.designate %1#0 (%c2:%c2:%13) shape %17 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + hlfir.assign %11 to %18 : !hlfir.expr, !fir.box> + hlfir.destroy %11 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @test_identical_1element_unknown_strides( +// CHECK-NOT: hlfir.elemental + +func.func @test_disjoint_1element_unknown_strides(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "s1"}, %arg2: !fir.ref {fir.bindc_name = "s2"}) { + %c2 = arith.constant 2 : index + %c1_i32 = arith.constant 1 : i32 + %c0 = arith.constant 0 : index + %c3 = arith.constant 3 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEa"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEs1"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %3:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestEs2"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %4 = fir.load %3#0 : !fir.ref + %5 = fir.convert %4 : (i32) -> index + %6 = arith.divsi %5, %5 : index + %7 = arith.cmpi sgt, %6, %c0 : index + %8 = arith.select %7, %6, %c0 : index + %9 = fir.shape %8 : (index) -> !fir.shape<1> + %10 = hlfir.designate %1#0 (%c3:%c3:%5) shape %9 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + %11 = hlfir.elemental %9 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg3: index): + %19 = hlfir.designate %10 (%arg3) : (!fir.box>, index) -> !fir.ref + %20 = fir.load %19 : !fir.ref + %21 = arith.addi %20, %c1_i32 : i32 + hlfir.yield_element %21 : i32 + } + %12 = fir.load %2#0 : !fir.ref + %13 = fir.convert %12 : (i32) -> index + %14 = arith.divsi %13, %13 : index + %15 = arith.cmpi sgt, %14, %c0 : index + %16 = arith.select %15, %14, %c0 : index + %17 = fir.shape %16 : (index) -> !fir.shape<1> + %18 = hlfir.designate %1#0 (%c2:%c2:%13) shape %17 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + hlfir.assign %11 to %18 : !hlfir.expr, !fir.box> + hlfir.destroy %11 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @test_disjoint_1element_unknown_strides( +// CHECK-NOT: hlfir.elemental + +// Check that 'a(x:y:1) = a(z:x-1:-1) + 1' is not optimized. +// The bounds are like in Polyhedron/nf, but the second +// stride is negative, so it cannot be optimized. +func.func @test_overlap_sub1_negative_stride(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.ref {fir.bindc_name = "x"}, %arg2: !fir.ref {fir.bindc_name = "y"}, %arg3: !fir.ref {fir.bindc_name = "z"}) { + %c1 = arith.constant 1 : index + %c0 = arith.constant 0 : index + %c-1 = arith.constant -1 : index + %c1_i32 = arith.constant 1 : i32 + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEa"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %3:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestEy"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %4:2 = hlfir.declare %arg3 dummy_scope %0 {uniq_name = "_QFtestEz"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %5 = fir.load %4#0 : !fir.ref + %6 = fir.load %2#0 : !fir.ref + %7 = arith.subi %6, %c1_i32 overflow : i32 + %8 = fir.convert %5 : (i32) -> index + %9 = fir.convert %7 : (i32) -> index + %10 = arith.subi %9, %8 : index + %11 = arith.addi %10, %c-1 : index + %12 = arith.divsi %11, %c-1 : index + %13 = arith.cmpi sgt, %12, %c0 : index + %14 = arith.select %13, %12, %c0 : index + %15 = fir.shape %14 : (index) -> !fir.shape<1> + %16 = hlfir.designate %1#0 (%8:%9:%c-1) shape %15 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + %17 = hlfir.elemental %15 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg4: index): + %27 = hlfir.designate %16 (%arg4) : (!fir.box>, index) -> !fir.ref + %28 = fir.load %27 : !fir.ref + %29 = arith.addi %28, %c1_i32 : i32 + hlfir.yield_element %29 : i32 + } + %18 = fir.load %3#0 : !fir.ref + %19 = fir.convert %6 : (i32) -> index + %20 = fir.convert %18 : (i32) -> index + %21 = arith.subi %20, %19 : index + %22 = arith.addi %21, %c1 : index + %23 = arith.cmpi sgt, %22, %c0 : index + %24 = arith.select %23, %22, %c0 : index + %25 = fir.shape %24 : (index) -> !fir.shape<1> + %26 = hlfir.designate %1#0 (%19:%20:%c1) shape %25 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + hlfir.assign %17 to %26 : !hlfir.expr, !fir.box> + hlfir.destroy %17 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @test_overlap_sub1_negative_stride( +// CHECK: hlfir.elemental + +// Check that 'x(1:5) = x(16:8:stride) + 1' is not optimized. +// TODO: because the bounds are known, we can still deduce +// no overlap: +// * If stride is negative, then (1:5) does not overlap +// with (8:16). +// * If stride is positive, then (16:8:stride) is an empty +// slice, thus it does not overlap with (1:5). +func.func @test_disjoint_known_bounds_unknown_stride(%arg0: !fir.box> {fir.bindc_name = "x"}, %arg1: !fir.ref {fir.bindc_name = "ub"}, %arg2: !fir.ref {fir.bindc_name = "stride"}) { + %c-8 = arith.constant -8 : index + %c5 = arith.constant 5 : index + %c1 = arith.constant 1 : index + %cst = arith.constant 1.000000e+00 : f32 + %c0 = arith.constant 0 : index + %c8 = arith.constant 8 : index + %c16 = arith.constant 16 : index + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg2 dummy_scope %0 {uniq_name = "_QFtestEstride"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEub"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) + %3:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEx"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %4 = fir.load %1#0 : !fir.ref + %5 = fir.convert %4 : (i32) -> index + %6 = arith.addi %5, %c-8 : index + %7 = arith.divsi %6, %5 : index + %8 = arith.cmpi sgt, %7, %c0 : index + %9 = arith.select %8, %7, %c0 : index + %10 = fir.shape %9 : (index) -> !fir.shape<1> + %11 = hlfir.designate %3#0 (%c16:%c8:%5) shape %10 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + %12 = hlfir.elemental %10 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg3: index): + %15 = hlfir.designate %11 (%arg3) : (!fir.box>, index) -> !fir.ref + %16 = fir.load %15 : !fir.ref + %17 = arith.addf %16, %cst fastmath : f32 + hlfir.yield_element %17 : f32 + } + %13 = fir.shape %c5 : (index) -> !fir.shape<1> + %14 = hlfir.designate %3#0 (%c1:%c5:%c1) shape %13 : (!fir.box>, index, index, index, !fir.shape<1>) -> !fir.box> + hlfir.assign %12 to %14 : !hlfir.expr, !fir.box> + hlfir.destroy %12 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @test_disjoint_known_bounds_unknown_stride( +// CHECK: hlfir.elemental diff --git a/flang/test/HLFIR/opt-bufferization-non-realloc-assignment.fir b/flang/test/HLFIR/opt-bufferization-non-realloc-assignment.fir new file mode 100644 index 0000000000000..cc65dec01cc3c --- /dev/null +++ b/flang/test/HLFIR/opt-bufferization-non-realloc-assignment.fir @@ -0,0 +1,50 @@ +// RUN: fir-opt --opt-bufferization %s | FileCheck %s + +// Verify that the shape match is not required for optimizing +// elemental assignment, when lhs not an allocatable. +// The shapes of lhs and rhs must conform in a legal program. +// +// Example: +// subroutine test(a,b) +// integer :: a(:), b(:) +// a = b + 1 +// end subroutine test + +func.func @_QPtest(%arg0: !fir.box> {fir.bindc_name = "a"}, %arg1: !fir.box> {fir.bindc_name = "b"}) { + %c0 = arith.constant 0 : index + %c1_i32 = arith.constant 1 : i32 + %0 = fir.dummy_scope : !fir.dscope + %1:2 = hlfir.declare %arg0 dummy_scope %0 {uniq_name = "_QFtestEa"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %2:2 = hlfir.declare %arg1 dummy_scope %0 {uniq_name = "_QFtestEb"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) + %3:3 = fir.box_dims %2#0, %c0 : (!fir.box>, index) -> (index, index, index) + %4 = fir.shape %3#1 : (index) -> !fir.shape<1> + %5 = hlfir.elemental %4 unordered : (!fir.shape<1>) -> !hlfir.expr { + ^bb0(%arg2: index): + %6 = hlfir.designate %2#0 (%arg2) : (!fir.box>, index) -> !fir.ref + %7 = fir.load %6 : !fir.ref + %8 = arith.addi %7, %c1_i32 : i32 + hlfir.yield_element %8 : i32 + } + hlfir.assign %5 to %1#0 : !hlfir.expr, !fir.box> + hlfir.destroy %5 : !hlfir.expr + return +} +// CHECK-LABEL: func.func @_QPtest( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "a"}, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.box> {fir.bindc_name = "b"}) { +// CHECK: %[[VAL_2:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 +// CHECK: %[[VAL_5:.*]] = fir.dummy_scope : !fir.dscope +// CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_5]] {uniq_name = "_QFtestEa"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) +// CHECK: %[[VAL_7:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %[[VAL_5]] {uniq_name = "_QFtestEb"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) +// CHECK: %[[VAL_8:.*]]:3 = fir.box_dims %[[VAL_7]]#0, %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +// CHECK: fir.do_loop %[[VAL_9:.*]] = %[[VAL_2]] to %[[VAL_8]]#1 step %[[VAL_2]] unordered { +// CHECK: %[[VAL_10:.*]] = hlfir.designate %[[VAL_7]]#0 (%[[VAL_9]]) : (!fir.box>, index) -> !fir.ref +// CHECK: %[[VAL_11:.*]] = fir.load %[[VAL_10]] : !fir.ref +// CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_11]], %[[VAL_4]] : i32 +// CHECK: %[[VAL_13:.*]] = hlfir.designate %[[VAL_6]]#0 (%[[VAL_9]]) : (!fir.box>, index) -> !fir.ref +// CHECK: hlfir.assign %[[VAL_12]] to %[[VAL_13]] : i32, !fir.ref +// CHECK: } +// CHECK: return +// CHECK: } diff --git a/flang/test/HLFIR/shapeof.fir b/flang/test/HLFIR/shapeof.fir index b91efc276b62e..43e22dd320c18 100644 --- a/flang/test/HLFIR/shapeof.fir +++ b/flang/test/HLFIR/shapeof.fir @@ -27,3 +27,21 @@ func.func @shapeof2(%arg0: !hlfir.expr) -> !fir.shape<2> { // CHECK-ALL: %[[EXPR:.*]]: !hlfir.expr // CHECK-ALL-NEXT: %[[SHAPE:.*]] = hlfir.shape_of %[[EXPR]] : (!hlfir.expr) -> !fir.shape<2> // CHECK-ALL-NEXT: return %[[SHAPE]] + +// Checks hlfir.elemental -> hlfir.shape_of folding +func.func @shapeof_fold1(%extent: index) -> !fir.shape<1> { + %shape1 = fir.shape %extent : (index) -> !fir.shape<1> + %elem = hlfir.elemental %shape1 : (!fir.shape<1>) -> !hlfir.expr { + hlfir.yield_element %extent : index + } + %shape2 = hlfir.shape_of %elem : (!hlfir.expr) -> !fir.shape<1> + return %shape2 : !fir.shape<1> +} +// CHECK-ALL-LABEL: func.func @shapeof_fold1( +// CHECK-ALL-SAME: %[[VAL_0:.*]]: index) -> !fir.shape<1> { +// CHECK-CANON-NEXT: %[[VAL_1:.*]] = fir.shape %[[VAL_0]] : (index) -> !fir.shape<1> +// CHECK-CANON-NEXT: %[[VAL_2:.*]] = hlfir.elemental %[[VAL_1]] : (!fir.shape<1>) -> !hlfir.expr { +// CHECK-CANON-NEXT: hlfir.yield_element %[[VAL_0]] : index +// CHECK-CANON-NEXT: } +// CHECK-CANON-NEXT: return %[[VAL_1]] : !fir.shape<1> +// CHECK-CANON-NEXT: } diff --git a/flang/test/HLFIR/simplify-hlfir-intrinsics-cshift.fir b/flang/test/HLFIR/simplify-hlfir-intrinsics-cshift.fir new file mode 100644 index 0000000000000..d21d7755062ba --- /dev/null +++ b/flang/test/HLFIR/simplify-hlfir-intrinsics-cshift.fir @@ -0,0 +1,278 @@ +// Test hlfir.cshift simplification to hlfir.elemental: +// RUN: fir-opt --simplify-hlfir-intrinsics %s | FileCheck %s + +func.func @cshift_vector(%arg0: !fir.box>, %arg1: !fir.ref) -> !hlfir.expr{ + %res = hlfir.cshift %arg0 %arg1 : (!fir.box>, !fir.ref) -> !hlfir.expr + return %res : !hlfir.expr +} +// CHECK-LABEL: func.func @cshift_vector( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref) -> !hlfir.expr { +// CHECK: %[[VAL_26:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_16:.*]] = arith.constant 0 : i64 +// CHECK: %[[VAL_5:.*]] = arith.constant 1 : i64 +// CHECK: %[[VAL_2:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]]#1 : (index) -> !fir.shape<1> +// CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_1]] : !fir.ref +// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_6]] : (i32) -> i64 +// CHECK: %[[VAL_8:.*]] = hlfir.elemental %[[VAL_4]] unordered : (!fir.shape<1>) -> !hlfir.expr { +// CHECK: ^bb0(%[[VAL_9:.*]]: index): +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (index) -> i64 +// CHECK: %[[VAL_11:.*]] = arith.addi %[[VAL_10]], %[[VAL_7]] : i64 +// CHECK: %[[VAL_12:.*]] = arith.subi %[[VAL_11]], %[[VAL_5]] : i64 +// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_3]]#1 : (index) -> i64 +// CHECK: %[[VAL_14:.*]] = arith.remsi %[[VAL_12]], %[[VAL_13]] : i64 +// CHECK: %[[VAL_15:.*]] = arith.xori %[[VAL_12]], %[[VAL_13]] : i64 +// CHECK: %[[VAL_17:.*]] = arith.cmpi slt, %[[VAL_15]], %[[VAL_16]] : i64 +// CHECK: %[[VAL_18:.*]] = arith.cmpi ne, %[[VAL_14]], %[[VAL_16]] : i64 +// CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_18]], %[[VAL_17]] : i1 +// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_14]], %[[VAL_13]] : i64 +// CHECK: %[[VAL_21:.*]] = arith.select %[[VAL_19]], %[[VAL_20]], %[[VAL_14]] : i64 +// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_21]], %[[VAL_5]] : i64 +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (i64) -> index +// CHECK: %[[VAL_25:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_27:.*]] = arith.subi %[[VAL_25]]#0, %[[VAL_26]] : index +// CHECK: %[[VAL_28:.*]] = arith.addi %[[VAL_23]], %[[VAL_27]] : index +// CHECK: %[[VAL_29:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_28]]) : (!fir.box>, index) -> !fir.ref +// CHECK: %[[VAL_30:.*]] = fir.load %[[VAL_29]] : !fir.ref +// CHECK: hlfir.yield_element %[[VAL_30]] : i32 +// CHECK: } +// CHECK: return +// CHECK: } + +func.func @cshift_2d_by_scalar(%arg0: !fir.box>, %arg1: !fir.ref) -> !hlfir.expr { + %dim = arith.constant 2 : i32 + %res = hlfir.cshift %arg0 %arg1 dim %dim : (!fir.box>, !fir.ref, i32) -> !hlfir.expr + return %res : !hlfir.expr +} +// CHECK-LABEL: func.func @cshift_2d_by_scalar( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref) -> !hlfir.expr { +// CHECK: %[[VAL_20:.*]] = arith.constant 0 : i64 +// CHECK: %[[VAL_8:.*]] = arith.constant 1 : i64 +// CHECK: %[[VAL_5:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_4]]#1, %[[VAL_6]]#1 : (index, index) -> !fir.shape<2> +// CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_1]] : !fir.ref +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> i64 +// CHECK: %[[VAL_11:.*]] = hlfir.elemental %[[VAL_7]] unordered : (!fir.shape<2>) -> !hlfir.expr { +// CHECK: ^bb0(%[[VAL_12:.*]]: index, %[[VAL_13:.*]]: index): +// CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_13]] : (index) -> i64 +// CHECK: %[[VAL_15:.*]] = arith.addi %[[VAL_14]], %[[VAL_10]] : i64 +// CHECK: %[[VAL_16:.*]] = arith.subi %[[VAL_15]], %[[VAL_8]] : i64 +// CHECK: %[[VAL_17:.*]] = fir.convert %[[VAL_6]]#1 : (index) -> i64 +// CHECK: %[[VAL_18:.*]] = arith.remsi %[[VAL_16]], %[[VAL_17]] : i64 +// CHECK: %[[VAL_19:.*]] = arith.xori %[[VAL_16]], %[[VAL_17]] : i64 +// CHECK: %[[VAL_21:.*]] = arith.cmpi slt, %[[VAL_19]], %[[VAL_20]] : i64 +// CHECK: %[[VAL_22:.*]] = arith.cmpi ne, %[[VAL_18]], %[[VAL_20]] : i64 +// CHECK: %[[VAL_23:.*]] = arith.andi %[[VAL_22]], %[[VAL_21]] : i1 +// CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_18]], %[[VAL_17]] : i64 +// CHECK: %[[VAL_25:.*]] = arith.select %[[VAL_23]], %[[VAL_24]], %[[VAL_18]] : i64 +// CHECK: %[[VAL_26:.*]] = arith.addi %[[VAL_25]], %[[VAL_8]] : i64 +// CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_26]] : (i64) -> index +// CHECK: %[[VAL_29:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_31:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_33:.*]] = arith.subi %[[VAL_29]]#0, %[[VAL_5]] : index +// CHECK: %[[VAL_34:.*]] = arith.addi %[[VAL_12]], %[[VAL_33]] : index +// CHECK: %[[VAL_35:.*]] = arith.subi %[[VAL_31]]#0, %[[VAL_5]] : index +// CHECK: %[[VAL_36:.*]] = arith.addi %[[VAL_27]], %[[VAL_35]] : index +// CHECK: %[[VAL_37:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_34]], %[[VAL_36]]) : (!fir.box>, index, index) -> !fir.ref +// CHECK: %[[VAL_38:.*]] = fir.load %[[VAL_37]] : !fir.ref +// CHECK: hlfir.yield_element %[[VAL_38]] : i32 +// CHECK: } +// CHECK: return +// CHECK: } + +func.func @cshift_2d_by_vector(%arg0: !fir.box>, %arg1: !fir.box>) -> !hlfir.expr { + %dim = arith.constant 2 : i32 + %res = hlfir.cshift %arg0 %arg1 dim %dim : (!fir.box>, !fir.box>, i32) -> !hlfir.expr + return %res : !hlfir.expr +} +// CHECK-LABEL: func.func @cshift_2d_by_vector( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.box>) -> !hlfir.expr { +// CHECK: %[[VAL_26:.*]] = arith.constant 0 : i64 +// CHECK: %[[VAL_8:.*]] = arith.constant 1 : i64 +// CHECK: %[[VAL_5:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_6:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_7:.*]] = fir.shape %[[VAL_4]]#1, %[[VAL_6]]#1 : (index, index) -> !fir.shape<2> +// CHECK: %[[VAL_9:.*]] = hlfir.elemental %[[VAL_7]] unordered : (!fir.shape<2>) -> !hlfir.expr { +// CHECK: ^bb0(%[[VAL_10:.*]]: index, %[[VAL_11:.*]]: index): +// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_13]]#0, %[[VAL_5]] : index +// CHECK: %[[VAL_16:.*]] = arith.addi %[[VAL_10]], %[[VAL_15]] : index +// CHECK: %[[VAL_17:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_16]]) : (!fir.box>, index) -> !fir.ref +// CHECK: %[[VAL_18:.*]] = fir.load %[[VAL_17]] : !fir.ref +// CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (i32) -> i64 +// CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_11]] : (index) -> i64 +// CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_20]], %[[VAL_19]] : i64 +// CHECK: %[[VAL_22:.*]] = arith.subi %[[VAL_21]], %[[VAL_8]] : i64 +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_6]]#1 : (index) -> i64 +// CHECK: %[[VAL_24:.*]] = arith.remsi %[[VAL_22]], %[[VAL_23]] : i64 +// CHECK: %[[VAL_25:.*]] = arith.xori %[[VAL_22]], %[[VAL_23]] : i64 +// CHECK: %[[VAL_27:.*]] = arith.cmpi slt, %[[VAL_25]], %[[VAL_26]] : i64 +// CHECK: %[[VAL_28:.*]] = arith.cmpi ne, %[[VAL_24]], %[[VAL_26]] : i64 +// CHECK: %[[VAL_29:.*]] = arith.andi %[[VAL_28]], %[[VAL_27]] : i1 +// CHECK: %[[VAL_30:.*]] = arith.addi %[[VAL_24]], %[[VAL_23]] : i64 +// CHECK: %[[VAL_31:.*]] = arith.select %[[VAL_29]], %[[VAL_30]], %[[VAL_24]] : i64 +// CHECK: %[[VAL_32:.*]] = arith.addi %[[VAL_31]], %[[VAL_8]] : i64 +// CHECK: %[[VAL_33:.*]] = fir.convert %[[VAL_32]] : (i64) -> index +// CHECK: %[[VAL_35:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_37:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_39:.*]] = arith.subi %[[VAL_35]]#0, %[[VAL_5]] : index +// CHECK: %[[VAL_40:.*]] = arith.addi %[[VAL_10]], %[[VAL_39]] : index +// CHECK: %[[VAL_41:.*]] = arith.subi %[[VAL_37]]#0, %[[VAL_5]] : index +// CHECK: %[[VAL_42:.*]] = arith.addi %[[VAL_33]], %[[VAL_41]] : index +// CHECK: %[[VAL_43:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_40]], %[[VAL_42]]) : (!fir.box>, index, index) -> !fir.ref +// CHECK: %[[VAL_44:.*]] = fir.load %[[VAL_43]] : !fir.ref +// CHECK: hlfir.yield_element %[[VAL_44]] : i32 +// CHECK: } +// CHECK: return +// CHECK: } + +func.func @cshift_vector_char(%arg0: !fir.box>>, %arg1: !fir.ref) -> !hlfir.expr> { + %res = hlfir.cshift %arg0 %arg1 : (!fir.box>>, !fir.ref) -> !hlfir.expr> + return %res : !hlfir.expr> +} +// CHECK-LABEL: func.func @cshift_vector_char( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>>, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref) -> !hlfir.expr> { +// CHECK: %[[VAL_32:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_19:.*]] = arith.constant 0 : i64 +// CHECK: %[[VAL_8:.*]] = arith.constant 1 : i64 +// CHECK: %[[VAL_6:.*]] = arith.constant 2 : index +// CHECK: %[[VAL_2:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]]#1 : (index) -> !fir.shape<1> +// CHECK: %[[VAL_5:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box>>) -> index +// CHECK: %[[VAL_7:.*]] = arith.divsi %[[VAL_5]], %[[VAL_6]] : index +// CHECK: %[[VAL_9:.*]] = fir.load %[[VAL_1]] : !fir.ref +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (i32) -> i64 +// CHECK: %[[VAL_11:.*]] = hlfir.elemental %[[VAL_4]] typeparams %[[VAL_7]] unordered : (!fir.shape<1>, index) -> !hlfir.expr> { +// CHECK: ^bb0(%[[VAL_12:.*]]: index): +// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_12]] : (index) -> i64 +// CHECK: %[[VAL_14:.*]] = arith.addi %[[VAL_13]], %[[VAL_10]] : i64 +// CHECK: %[[VAL_15:.*]] = arith.subi %[[VAL_14]], %[[VAL_8]] : i64 +// CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_3]]#1 : (index) -> i64 +// CHECK: %[[VAL_17:.*]] = arith.remsi %[[VAL_15]], %[[VAL_16]] : i64 +// CHECK: %[[VAL_18:.*]] = arith.xori %[[VAL_15]], %[[VAL_16]] : i64 +// CHECK: %[[VAL_20:.*]] = arith.cmpi slt, %[[VAL_18]], %[[VAL_19]] : i64 +// CHECK: %[[VAL_21:.*]] = arith.cmpi ne, %[[VAL_17]], %[[VAL_19]] : i64 +// CHECK: %[[VAL_22:.*]] = arith.andi %[[VAL_21]], %[[VAL_20]] : i1 +// CHECK: %[[VAL_23:.*]] = arith.addi %[[VAL_17]], %[[VAL_16]] : i64 +// CHECK: %[[VAL_24:.*]] = arith.select %[[VAL_22]], %[[VAL_23]], %[[VAL_17]] : i64 +// CHECK: %[[VAL_25:.*]] = arith.addi %[[VAL_24]], %[[VAL_8]] : i64 +// CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (i64) -> index +// CHECK: %[[VAL_27:.*]] = fir.box_elesize %[[VAL_0]] : (!fir.box>>) -> index +// CHECK: %[[VAL_29:.*]] = arith.divsi %[[VAL_27]], %[[VAL_6]] : index +// CHECK: %[[VAL_31:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_33:.*]] = arith.subi %[[VAL_31]]#0, %[[VAL_32]] : index +// CHECK: %[[VAL_34:.*]] = arith.addi %[[VAL_26]], %[[VAL_33]] : index +// CHECK: %[[VAL_35:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_34]]) typeparams %[[VAL_29]] : (!fir.box>>, index, index) -> !fir.boxchar<2> +// CHECK: hlfir.yield_element %[[VAL_35]] : !fir.boxchar<2> +// CHECK: } +// CHECK: return +// CHECK: } + +func.func @cshift_vector_poly(%arg0: !fir.class>>, %arg1: i32) -> !hlfir.expr?> { + %res = hlfir.cshift %arg0 %arg1 : (!fir.class>>, i32) -> !hlfir.expr?> + return %res : !hlfir.expr?> +} +// CHECK-LABEL: func.func @cshift_vector_poly( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.class>>, +// CHECK-SAME: %[[VAL_1:.*]]: i32) -> !hlfir.expr?> { +// CHECK: %[[VAL_25:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_15:.*]] = arith.constant 0 : i64 +// CHECK: %[[VAL_5:.*]] = arith.constant 1 : i64 +// CHECK: %[[VAL_2:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.class>>, index) -> (index, index, index) +// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]]#1 : (index) -> !fir.shape<1> +// CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_1]] : (i32) -> i64 +// CHECK: %[[VAL_7:.*]] = hlfir.elemental %[[VAL_4]] mold %[[VAL_0]] unordered : (!fir.shape<1>, !fir.class>>) -> !hlfir.expr?> { +// CHECK: ^bb0(%[[VAL_8:.*]]: index): +// CHECK: %[[VAL_9:.*]] = fir.convert %[[VAL_8]] : (index) -> i64 +// CHECK: %[[VAL_10:.*]] = arith.addi %[[VAL_9]], %[[VAL_6]] : i64 +// CHECK: %[[VAL_11:.*]] = arith.subi %[[VAL_10]], %[[VAL_5]] : i64 +// CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_3]]#1 : (index) -> i64 +// CHECK: %[[VAL_13:.*]] = arith.remsi %[[VAL_11]], %[[VAL_12]] : i64 +// CHECK: %[[VAL_14:.*]] = arith.xori %[[VAL_11]], %[[VAL_12]] : i64 +// CHECK: %[[VAL_16:.*]] = arith.cmpi slt, %[[VAL_14]], %[[VAL_15]] : i64 +// CHECK: %[[VAL_17:.*]] = arith.cmpi ne, %[[VAL_13]], %[[VAL_15]] : i64 +// CHECK: %[[VAL_18:.*]] = arith.andi %[[VAL_17]], %[[VAL_16]] : i1 +// CHECK: %[[VAL_19:.*]] = arith.addi %[[VAL_13]], %[[VAL_12]] : i64 +// CHECK: %[[VAL_20:.*]] = arith.select %[[VAL_18]], %[[VAL_19]], %[[VAL_13]] : i64 +// CHECK: %[[VAL_21:.*]] = arith.addi %[[VAL_20]], %[[VAL_5]] : i64 +// CHECK: %[[VAL_22:.*]] = fir.convert %[[VAL_21]] : (i64) -> index +// CHECK: %[[VAL_24:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.class>>, index) -> (index, index, index) +// CHECK: %[[VAL_26:.*]] = arith.subi %[[VAL_24]]#0, %[[VAL_25]] : index +// CHECK: %[[VAL_27:.*]] = arith.addi %[[VAL_22]], %[[VAL_26]] : index +// CHECK: %[[VAL_28:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_27]]) : (!fir.class>>, index) -> !fir.class> +// CHECK: hlfir.yield_element %[[VAL_28]] : !fir.class> +// CHECK: } +// CHECK: return +// CHECK: } + +// negative: non-constant dim argument +func.func @cshift_nonconst_dim(%arg0: !fir.box>, %arg1: i32, %dim : i32) -> !hlfir.expr { + %res = hlfir.cshift %arg0 %arg1 dim %dim : (!fir.box>, i32, i32) -> !hlfir.expr + return %res : !hlfir.expr +} +// CHECK-LABEL: func.func @cshift_nonconst_dim( +// CHECK: hlfir.cshift {{.*}} : (!fir.box>, i32, i32) -> !hlfir.expr + +// negative: invalid constant dim argument +func.func @cshift_invalid_dim(%arg0: !fir.box>, %arg1: i32) -> !hlfir.expr { + %dim = arith.constant 3 : i32 + %res = hlfir.cshift %arg0 %arg1 dim %dim : (!fir.box>, i32, i32) -> !hlfir.expr + return %res : !hlfir.expr +} +// CHECK-LABEL: func.func @cshift_invalid_dim( +// CHECK: hlfir.cshift {{.*}} : (!fir.box>, i32, i32) -> !hlfir.expr + +// When the input array is 1D, we may assume that DIM==1, +// otherwise the program is illegal, and we can do anything +// about it. +func.func @cshift_vector_assumed_dim_1(%arg0: !fir.box>, %arg1: i32) -> !hlfir.expr { + %dim = arith.constant 3 : i32 + %res = hlfir.cshift %arg0 %arg1 dim %dim : (!fir.box>, i32, i32) -> !hlfir.expr + return %res : !hlfir.expr +} +// CHECK-LABEL: func.func @cshift_vector_assumed_dim_1( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>, +// CHECK-SAME: %[[VAL_1:.*]]: i32) -> !hlfir.expr { +// CHECK: %[[VAL_26:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_16:.*]] = arith.constant 0 : i64 +// CHECK: %[[VAL_6:.*]] = arith.constant 1 : i64 +// CHECK: %[[VAL_3:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_4:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]]#1 : (index) -> !fir.shape<1> +// CHECK: %[[VAL_7:.*]] = fir.convert %[[VAL_1]] : (i32) -> i64 +// CHECK: %[[VAL_8:.*]] = hlfir.elemental %[[VAL_5]] unordered : (!fir.shape<1>) -> !hlfir.expr { +// CHECK: ^bb0(%[[VAL_9:.*]]: index): +// CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_9]] : (index) -> i64 +// CHECK: %[[VAL_11:.*]] = arith.addi %[[VAL_10]], %[[VAL_7]] : i64 +// CHECK: %[[VAL_12:.*]] = arith.subi %[[VAL_11]], %[[VAL_6]] : i64 +// CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_4]]#1 : (index) -> i64 +// CHECK: %[[VAL_14:.*]] = arith.remsi %[[VAL_12]], %[[VAL_13]] : i64 +// CHECK: %[[VAL_15:.*]] = arith.xori %[[VAL_12]], %[[VAL_13]] : i64 +// CHECK: %[[VAL_17:.*]] = arith.cmpi slt, %[[VAL_15]], %[[VAL_16]] : i64 +// CHECK: %[[VAL_18:.*]] = arith.cmpi ne, %[[VAL_14]], %[[VAL_16]] : i64 +// CHECK: %[[VAL_19:.*]] = arith.andi %[[VAL_18]], %[[VAL_17]] : i1 +// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_14]], %[[VAL_13]] : i64 +// CHECK: %[[VAL_21:.*]] = arith.select %[[VAL_19]], %[[VAL_20]], %[[VAL_14]] : i64 +// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_21]], %[[VAL_6]] : i64 +// CHECK: %[[VAL_23:.*]] = fir.convert %[[VAL_22]] : (i64) -> index +// CHECK: %[[VAL_25:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_3]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_27:.*]] = arith.subi %[[VAL_25]]#0, %[[VAL_26]] : index +// CHECK: %[[VAL_28:.*]] = arith.addi %[[VAL_23]], %[[VAL_27]] : index +// CHECK: %[[VAL_29:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_28]]) : (!fir.box>, index) -> !fir.ref +// CHECK: %[[VAL_30:.*]] = fir.load %[[VAL_29]] : !fir.ref +// CHECK: hlfir.yield_element %[[VAL_30]] : i32 +// CHECK: } +// CHECK: return +// CHECK: } diff --git a/flang/test/HLFIR/simplify-hlfir-intrinsics-sum.fir b/flang/test/HLFIR/simplify-hlfir-intrinsics-sum.fir new file mode 100644 index 0000000000000..58a2144947b14 --- /dev/null +++ b/flang/test/HLFIR/simplify-hlfir-intrinsics-sum.fir @@ -0,0 +1,439 @@ +// RUN: fir-opt --simplify-hlfir-intrinsics -flang-simplify-hlfir-sum %s | FileCheck %s + +// box with known extents +func.func @sum_box_known_extents(%arg0: !fir.box>) -> !hlfir.expr<2xi32> { + %cst = arith.constant 2 : i32 + %res = hlfir.sum %arg0 dim %cst : (!fir.box>, i32) -> !hlfir.expr<2xi32> + return %res : !hlfir.expr<2xi32> +} +// CHECK-LABEL: func.func @sum_box_known_extents( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>) -> !hlfir.expr<2xi32> { +// CHECK: %[[VAL_12:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_8:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_7:.*]] = arith.constant 0 : i32 +// CHECK: %[[VAL_2:.*]] = arith.constant 2 : index +// CHECK: %[[VAL_3:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_2]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_5:.*]] = hlfir.elemental %[[VAL_4]] unordered : (!fir.shape<1>) -> !hlfir.expr<2xi32> { +// CHECK: ^bb0(%[[VAL_6:.*]]: index): +// CHECK: %[[VAL_9:.*]] = fir.do_loop %[[VAL_10:.*]] = %[[VAL_8]] to %[[VAL_3]] step %[[VAL_8]] unordered iter_args(%[[VAL_11:.*]] = %[[VAL_7]]) -> (i32) { +// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_12]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_8]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_13]]#0, %[[VAL_8]] : index +// CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_6]], %[[VAL_17]] : index +// CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_15]]#0, %[[VAL_8]] : index +// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_10]], %[[VAL_19]] : index +// CHECK: %[[VAL_21:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_18]], %[[VAL_20]]) : (!fir.box>, index, index) -> !fir.ref +// CHECK: %[[VAL_22:.*]] = fir.load %[[VAL_21]] : !fir.ref +// CHECK: %[[VAL_23:.*]] = arith.addi %[[VAL_11]], %[[VAL_22]] : i32 +// CHECK: fir.result %[[VAL_23]] : i32 +// CHECK: } +// CHECK: hlfir.yield_element %[[VAL_9]] : i32 +// CHECK: } +// CHECK: return +// CHECK: } + +// expr with known extents +func.func @sum_expr_known_extents(%arg0: !hlfir.expr<2x3xi32>) -> !hlfir.expr<3xi32> { + %cst = arith.constant 1 : i32 + %res = hlfir.sum %arg0 dim %cst : (!hlfir.expr<2x3xi32>, i32) -> !hlfir.expr<3xi32> + return %res : !hlfir.expr<3xi32> +} +// CHECK-LABEL: func.func @sum_expr_known_extents( +// CHECK-SAME: %[[VAL_0:.*]]: !hlfir.expr<2x3xi32>) -> !hlfir.expr<3xi32> { +// CHECK: %[[VAL_8:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_7:.*]] = arith.constant 0 : i32 +// CHECK: %[[VAL_2:.*]] = arith.constant 2 : index +// CHECK: %[[VAL_3:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_5:.*]] = hlfir.elemental %[[VAL_4]] unordered : (!fir.shape<1>) -> !hlfir.expr<3xi32> { +// CHECK: ^bb0(%[[VAL_6:.*]]: index): +// CHECK: %[[VAL_9:.*]] = fir.do_loop %[[VAL_10:.*]] = %[[VAL_8]] to %[[VAL_2]] step %[[VAL_8]] unordered iter_args(%[[VAL_11:.*]] = %[[VAL_7]]) -> (i32) { +// CHECK: %[[VAL_12:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_10]], %[[VAL_6]] : (!hlfir.expr<2x3xi32>, index, index) -> i32 +// CHECK: %[[VAL_13:.*]] = arith.addi %[[VAL_11]], %[[VAL_12]] : i32 +// CHECK: fir.result %[[VAL_13]] : i32 +// CHECK: } +// CHECK: hlfir.yield_element %[[VAL_9]] : i32 +// CHECK: } +// CHECK: return +// CHECK: } + +// box with unknown extent +func.func @sum_box_unknown_extent1(%arg0: !fir.box>>) -> !hlfir.expr<3xcomplex> { + %cst = arith.constant 1 : i32 + %res = hlfir.sum %arg0 dim %cst : (!fir.box>>, i32) -> !hlfir.expr<3xcomplex> + return %res : !hlfir.expr<3xcomplex> +} +// CHECK-LABEL: func.func @sum_box_unknown_extent1( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>>) -> !hlfir.expr<3xcomplex> { +// CHECK: %[[VAL_12:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_8:.*]] = arith.constant 0.000000e+00 : f64 +// CHECK: %[[VAL_4:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_2:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_6:.*]] = hlfir.elemental %[[VAL_5]] unordered : (!fir.shape<1>) -> !hlfir.expr<3xcomplex> { +// CHECK: ^bb0(%[[VAL_7:.*]]: index): +// CHECK: %[[VAL_9:.*]] = fir.undefined complex +// CHECK: %[[VAL_10:.*]] = fir.insert_value %[[VAL_9]], %[[VAL_8]], [0 : index] : (complex, f64) -> complex +// CHECK: %[[VAL_11:.*]] = fir.insert_value %[[VAL_10]], %[[VAL_8]], [1 : index] : (complex, f64) -> complex +// CHECK: %[[VAL_13:.*]] = fir.do_loop %[[VAL_14:.*]] = %[[VAL_12]] to %[[VAL_3]]#1 step %[[VAL_12]] iter_args(%[[VAL_15:.*]] = %[[VAL_11]]) -> (complex) { +// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_19:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_12]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_21:.*]] = arith.subi %[[VAL_17]]#0, %[[VAL_12]] : index +// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_14]], %[[VAL_21]] : index +// CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_19]]#0, %[[VAL_12]] : index +// CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_7]], %[[VAL_23]] : index +// CHECK: %[[VAL_25:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_22]], %[[VAL_24]]) : (!fir.box>>, index, index) -> !fir.ref> +// CHECK: %[[VAL_26:.*]] = fir.load %[[VAL_25]] : !fir.ref> +// CHECK: %[[VAL_27:.*]] = fir.addc %[[VAL_15]], %[[VAL_26]] : complex +// CHECK: fir.result %[[VAL_27]] : complex +// CHECK: } +// CHECK: hlfir.yield_element %[[VAL_13]] : complex +// CHECK: } +// CHECK: return +// CHECK: } + +func.func @sum_box_unknown_extent2(%arg0: !fir.box>>) -> !hlfir.expr> { + %cst = arith.constant 2 : i32 + %res = hlfir.sum %arg0 dim %cst : (!fir.box>>, i32) -> !hlfir.expr> + return %res : !hlfir.expr> +} +// CHECK-LABEL: func.func @sum_box_unknown_extent2( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>>) -> !hlfir.expr> { +// CHECK: %[[VAL_12:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_8:.*]] = arith.constant 0.000000e+00 : f64 +// CHECK: %[[VAL_4:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_2:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_3:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_3]]#1 : (index) -> !fir.shape<1> +// CHECK: %[[VAL_6:.*]] = hlfir.elemental %[[VAL_5]] unordered : (!fir.shape<1>) -> !hlfir.expr> { +// CHECK: ^bb0(%[[VAL_7:.*]]: index): +// CHECK: %[[VAL_9:.*]] = fir.undefined complex +// CHECK: %[[VAL_10:.*]] = fir.insert_value %[[VAL_9]], %[[VAL_8]], [0 : index] : (complex, f64) -> complex +// CHECK: %[[VAL_11:.*]] = fir.insert_value %[[VAL_10]], %[[VAL_8]], [1 : index] : (complex, f64) -> complex +// CHECK: %[[VAL_13:.*]] = fir.do_loop %[[VAL_14:.*]] = %[[VAL_12]] to %[[VAL_4]] step %[[VAL_12]] iter_args(%[[VAL_15:.*]] = %[[VAL_11]]) -> (complex) { +// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_2]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_19:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_12]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_21:.*]] = arith.subi %[[VAL_17]]#0, %[[VAL_12]] : index +// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_7]], %[[VAL_21]] : index +// CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_19]]#0, %[[VAL_12]] : index +// CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_14]], %[[VAL_23]] : index +// CHECK: %[[VAL_25:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_22]], %[[VAL_24]]) : (!fir.box>>, index, index) -> !fir.ref> +// CHECK: %[[VAL_26:.*]] = fir.load %[[VAL_25]] : !fir.ref> +// CHECK: %[[VAL_27:.*]] = fir.addc %[[VAL_15]], %[[VAL_26]] : complex +// CHECK: fir.result %[[VAL_27]] : complex +// CHECK: } +// CHECK: hlfir.yield_element %[[VAL_13]] : complex +// CHECK: } +// CHECK: return +// CHECK: } + +// expr with unknown extent +func.func @sum_expr_unknown_extent1(%arg0: !hlfir.expr) -> !hlfir.expr<3xf32> { + %cst = arith.constant 1 : i32 + %res = hlfir.sum %arg0 dim %cst : (!hlfir.expr, i32) -> !hlfir.expr<3xf32> + return %res : !hlfir.expr<3xf32> +} +// CHECK-LABEL: func.func @sum_expr_unknown_extent1( +// CHECK-SAME: %[[VAL_0:.*]]: !hlfir.expr) -> !hlfir.expr<3xf32> { +// CHECK: %[[VAL_9:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_8:.*]] = arith.constant 0.000000e+00 : f32 +// CHECK: %[[VAL_4:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_2:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<2> +// CHECK: %[[VAL_3:.*]] = hlfir.get_extent %[[VAL_2]] {dim = 0 : index} : (!fir.shape<2>) -> index +// CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_6:.*]] = hlfir.elemental %[[VAL_5]] unordered : (!fir.shape<1>) -> !hlfir.expr<3xf32> { +// CHECK: ^bb0(%[[VAL_7:.*]]: index): +// CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_9]] to %[[VAL_3]] step %[[VAL_9]] iter_args(%[[VAL_12:.*]] = %[[VAL_8]]) -> (f32) { +// CHECK: %[[VAL_13:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_11]], %[[VAL_7]] : (!hlfir.expr, index, index) -> f32 +// CHECK: %[[VAL_14:.*]] = arith.addf %[[VAL_12]], %[[VAL_13]] : f32 +// CHECK: fir.result %[[VAL_14]] : f32 +// CHECK: } +// CHECK: hlfir.yield_element %[[VAL_10]] : f32 +// CHECK: } +// CHECK: return +// CHECK: } + +func.func @sum_expr_unknown_extent2(%arg0: !hlfir.expr) -> !hlfir.expr { + %cst = arith.constant 2 : i32 + %res = hlfir.sum %arg0 dim %cst : (!hlfir.expr, i32) -> !hlfir.expr + return %res : !hlfir.expr +} +// CHECK-LABEL: func.func @sum_expr_unknown_extent2( +// CHECK-SAME: %[[VAL_0:.*]]: !hlfir.expr) -> !hlfir.expr { +// CHECK: %[[VAL_9:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_8:.*]] = arith.constant 0.000000e+00 : f32 +// CHECK: %[[VAL_4:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_2:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<2> +// CHECK: %[[VAL_3:.*]] = hlfir.get_extent %[[VAL_2]] {dim = 0 : index} : (!fir.shape<2>) -> index +// CHECK: %[[VAL_5:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_6:.*]] = hlfir.elemental %[[VAL_5]] unordered : (!fir.shape<1>) -> !hlfir.expr { +// CHECK: ^bb0(%[[VAL_7:.*]]: index): +// CHECK: %[[VAL_10:.*]] = fir.do_loop %[[VAL_11:.*]] = %[[VAL_9]] to %[[VAL_4]] step %[[VAL_9]] iter_args(%[[VAL_12:.*]] = %[[VAL_8]]) -> (f32) { +// CHECK: %[[VAL_13:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_7]], %[[VAL_11]] : (!hlfir.expr, index, index) -> f32 +// CHECK: %[[VAL_14:.*]] = arith.addf %[[VAL_12]], %[[VAL_13]] : f32 +// CHECK: fir.result %[[VAL_14]] : f32 +// CHECK: } +// CHECK: hlfir.yield_element %[[VAL_10]] : f32 +// CHECK: } +// CHECK: return +// CHECK: } + +// scalar mask +func.func @sum_scalar_mask(%arg0: !hlfir.expr, %mask: !fir.ref>) -> !hlfir.expr<3xf32> { + %cst = arith.constant 1 : i32 + %res = hlfir.sum %arg0 dim %cst mask %mask : (!hlfir.expr, i32, !fir.ref>) -> !hlfir.expr<3xf32> + return %res : !hlfir.expr<3xf32> +} +// CHECK-LABEL: func.func @sum_scalar_mask( +// CHECK-SAME: %[[VAL_0:.*]]: !hlfir.expr, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.ref>) -> !hlfir.expr<3xf32> { +// CHECK: %[[VAL_11:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_10:.*]] = arith.constant 0.000000e+00 : f32 +// CHECK: %[[VAL_5:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_3:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<2> +// CHECK: %[[VAL_4:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 0 : index} : (!fir.shape<2>) -> index +// CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_7:.*]] = fir.load %[[VAL_1]] : !fir.ref> +// CHECK: %[[VAL_8:.*]] = hlfir.elemental %[[VAL_6]] unordered : (!fir.shape<1>) -> !hlfir.expr<3xf32> { +// CHECK: ^bb0(%[[VAL_9:.*]]: index): +// CHECK: %[[VAL_12:.*]] = fir.do_loop %[[VAL_13:.*]] = %[[VAL_11]] to %[[VAL_4]] step %[[VAL_11]] iter_args(%[[VAL_14:.*]] = %[[VAL_10]]) -> (f32) { +// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_7]] : (!fir.logical<1>) -> i1 +// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_15]] -> (f32) { +// CHECK: %[[VAL_17:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_13]], %[[VAL_9]] : (!hlfir.expr, index, index) -> f32 +// CHECK: %[[VAL_18:.*]] = arith.addf %[[VAL_14]], %[[VAL_17]] : f32 +// CHECK: fir.result %[[VAL_18]] : f32 +// CHECK: } else { +// CHECK: fir.result %[[VAL_14]] : f32 +// CHECK: } +// CHECK: fir.result %[[VAL_16]] : f32 +// CHECK: } +// CHECK: hlfir.yield_element %[[VAL_12]] : f32 +// CHECK: } +// CHECK: return +// CHECK: } + +// scalar boxed mask +func.func @sum_scalar_boxed_mask(%arg0: !hlfir.expr, %mask: !fir.box>) -> !hlfir.expr<3xf32> { + %cst = arith.constant 1 : i32 + %res = hlfir.sum %arg0 dim %cst mask %mask : (!hlfir.expr, i32, !fir.box>) -> !hlfir.expr<3xf32> + return %res : !hlfir.expr<3xf32> +} +// CHECK-LABEL: func.func @sum_scalar_boxed_mask( +// CHECK-SAME: %[[VAL_0:.*]]: !hlfir.expr, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.box>) -> !hlfir.expr<3xf32> { +// CHECK: %[[VAL_16:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_15:.*]] = arith.constant 0.000000e+00 : f32 +// CHECK: %[[VAL_11:.*]] = arith.constant true +// CHECK: %[[VAL_5:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_3:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<2> +// CHECK: %[[VAL_4:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 0 : index} : (!fir.shape<2>) -> index +// CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_5]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>) -> i1 +// CHECK: %[[VAL_8:.*]] = fir.if %[[VAL_7]] -> (!fir.logical<1>) { +// CHECK: %[[VAL_9:.*]] = fir.box_addr %[[VAL_1]] : (!fir.box>) -> !fir.ref> +// CHECK: %[[VAL_10:.*]] = fir.load %[[VAL_9]] : !fir.ref> +// CHECK: fir.result %[[VAL_10]] : !fir.logical<1> +// CHECK: } else { +// CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_11]] : (i1) -> !fir.logical<1> +// CHECK: fir.result %[[VAL_12]] : !fir.logical<1> +// CHECK: } +// CHECK: %[[VAL_13:.*]] = hlfir.elemental %[[VAL_6]] unordered : (!fir.shape<1>) -> !hlfir.expr<3xf32> { +// CHECK: ^bb0(%[[VAL_14:.*]]: index): +// CHECK: %[[VAL_17:.*]] = fir.do_loop %[[VAL_18:.*]] = %[[VAL_16]] to %[[VAL_4]] step %[[VAL_16]] iter_args(%[[VAL_19:.*]] = %[[VAL_15]]) -> (f32) { +// CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_8]] : (!fir.logical<1>) -> i1 +// CHECK: %[[VAL_21:.*]] = fir.if %[[VAL_20]] -> (f32) { +// CHECK: %[[VAL_22:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_18]], %[[VAL_14]] : (!hlfir.expr, index, index) -> f32 +// CHECK: %[[VAL_23:.*]] = arith.addf %[[VAL_19]], %[[VAL_22]] : f32 +// CHECK: fir.result %[[VAL_23]] : f32 +// CHECK: } else { +// CHECK: fir.result %[[VAL_19]] : f32 +// CHECK: } +// CHECK: fir.result %[[VAL_21]] : f32 +// CHECK: } +// CHECK: hlfir.yield_element %[[VAL_17]] : f32 +// CHECK: } +// CHECK: return +// CHECK: } + +// array mask +func.func @sum_array_mask(%arg0: !hlfir.expr, %mask: !fir.box>>) -> !hlfir.expr { + %cst = arith.constant 2 : i32 + %res = hlfir.sum %arg0 dim %cst mask %mask : (!hlfir.expr, i32, !fir.box>>) -> !hlfir.expr + return %res : !hlfir.expr +} +// CHECK-LABEL: func.func @sum_array_mask( +// CHECK-SAME: %[[VAL_0:.*]]: !hlfir.expr, +// CHECK-SAME: %[[VAL_1:.*]]: !fir.box>>) -> !hlfir.expr { +// CHECK: %[[VAL_27:.*]] = arith.constant true +// CHECK: %[[VAL_16:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_11:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_10:.*]] = arith.constant 0.000000e+00 : f32 +// CHECK: %[[VAL_5:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_3:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<2> +// CHECK: %[[VAL_4:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 0 : index} : (!fir.shape<2>) -> index +// CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_7:.*]] = fir.is_present %[[VAL_1]] : (!fir.box>>) -> i1 +// CHECK: %[[VAL_8:.*]] = hlfir.elemental %[[VAL_6]] unordered : (!fir.shape<1>) -> !hlfir.expr { +// CHECK: ^bb0(%[[VAL_9:.*]]: index): +// CHECK: %[[VAL_12:.*]] = fir.do_loop %[[VAL_13:.*]] = %[[VAL_11]] to %[[VAL_5]] step %[[VAL_11]] iter_args(%[[VAL_14:.*]] = %[[VAL_10]]) -> (f32) { +// CHECK: %[[VAL_15:.*]] = fir.if %[[VAL_7]] -> (!fir.logical<1>) { +// CHECK: %[[VAL_17:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_16]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_19:.*]]:3 = fir.box_dims %[[VAL_1]], %[[VAL_11]] : (!fir.box>>, index) -> (index, index, index) +// CHECK: %[[VAL_21:.*]] = arith.subi %[[VAL_17]]#0, %[[VAL_11]] : index +// CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_9]], %[[VAL_21]] : index +// CHECK: %[[VAL_23:.*]] = arith.subi %[[VAL_19]]#0, %[[VAL_11]] : index +// CHECK: %[[VAL_24:.*]] = arith.addi %[[VAL_13]], %[[VAL_23]] : index +// CHECK: %[[VAL_25:.*]] = hlfir.designate %[[VAL_1]] (%[[VAL_22]], %[[VAL_24]]) : (!fir.box>>, index, index) -> !fir.ref> +// CHECK: %[[VAL_26:.*]] = fir.load %[[VAL_25]] : !fir.ref> +// CHECK: fir.result %[[VAL_26]] : !fir.logical<1> +// CHECK: } else { +// CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_27]] : (i1) -> !fir.logical<1> +// CHECK: fir.result %[[VAL_28]] : !fir.logical<1> +// CHECK: } +// CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_15]] : (!fir.logical<1>) -> i1 +// CHECK: %[[VAL_30:.*]] = fir.if %[[VAL_29]] -> (f32) { +// CHECK: %[[VAL_31:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_9]], %[[VAL_13]] : (!hlfir.expr, index, index) -> f32 +// CHECK: %[[VAL_32:.*]] = arith.addf %[[VAL_14]], %[[VAL_31]] : f32 +// CHECK: fir.result %[[VAL_32]] : f32 +// CHECK: } else { +// CHECK: fir.result %[[VAL_14]] : f32 +// CHECK: } +// CHECK: fir.result %[[VAL_30]] : f32 +// CHECK: } +// CHECK: hlfir.yield_element %[[VAL_12]] : f32 +// CHECK: } +// CHECK: return +// CHECK: } + +// array expr mask +func.func @sum_array_expr_mask(%arg0: !hlfir.expr, %mask: !hlfir.expr>) -> !hlfir.expr { + %cst = arith.constant 2 : i32 + %res = hlfir.sum %arg0 dim %cst mask %mask : (!hlfir.expr, i32, !hlfir.expr>) -> !hlfir.expr + return %res : !hlfir.expr +} +// CHECK-LABEL: func.func @sum_array_expr_mask( +// CHECK-SAME: %[[VAL_0:.*]]: !hlfir.expr, +// CHECK-SAME: %[[VAL_1:.*]]: !hlfir.expr>) -> !hlfir.expr { +// CHECK: %[[VAL_10:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_9:.*]] = arith.constant 0.000000e+00 : f32 +// CHECK: %[[VAL_5:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_3:.*]] = hlfir.shape_of %[[VAL_0]] : (!hlfir.expr) -> !fir.shape<2> +// CHECK: %[[VAL_4:.*]] = hlfir.get_extent %[[VAL_3]] {dim = 0 : index} : (!fir.shape<2>) -> index +// CHECK: %[[VAL_6:.*]] = fir.shape %[[VAL_4]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_7:.*]] = hlfir.elemental %[[VAL_6]] unordered : (!fir.shape<1>) -> !hlfir.expr { +// CHECK: ^bb0(%[[VAL_8:.*]]: index): +// CHECK: %[[VAL_11:.*]] = fir.do_loop %[[VAL_12:.*]] = %[[VAL_10]] to %[[VAL_5]] step %[[VAL_10]] iter_args(%[[VAL_13:.*]] = %[[VAL_9]]) -> (f32) { +// CHECK: %[[VAL_14:.*]] = hlfir.apply %[[VAL_1]], %[[VAL_8]], %[[VAL_12]] : (!hlfir.expr>, index, index) -> !fir.logical<1> +// CHECK: %[[VAL_15:.*]] = fir.convert %[[VAL_14]] : (!fir.logical<1>) -> i1 +// CHECK: %[[VAL_16:.*]] = fir.if %[[VAL_15]] -> (f32) { +// CHECK: %[[VAL_17:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_8]], %[[VAL_12]] : (!hlfir.expr, index, index) -> f32 +// CHECK: %[[VAL_18:.*]] = arith.addf %[[VAL_13]], %[[VAL_17]] : f32 +// CHECK: fir.result %[[VAL_18]] : f32 +// CHECK: } else { +// CHECK: fir.result %[[VAL_13]] : f32 +// CHECK: } +// CHECK: fir.result %[[VAL_16]] : f32 +// CHECK: } +// CHECK: hlfir.yield_element %[[VAL_11]] : f32 +// CHECK: } +// CHECK: return +// CHECK: } + +// unordered floating point reduction +func.func @sum_unordered_reduction(%arg0: !hlfir.expr<2x3xf32>) -> !hlfir.expr<3xf32> { + %cst = arith.constant 1 : i32 + %res = hlfir.sum %arg0 dim %cst {fastmath = #arith.fastmath} : (!hlfir.expr<2x3xf32>, i32) -> !hlfir.expr<3xf32> + return %res : !hlfir.expr<3xf32> +} +// CHECK-LABEL: func.func @sum_unordered_reduction( +// CHECK-SAME: %[[VAL_0:.*]]: !hlfir.expr<2x3xf32>) -> !hlfir.expr<3xf32> { +// CHECK: %[[VAL_8:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_7:.*]] = arith.constant 0.000000e+00 : f32 +// CHECK: %[[VAL_2:.*]] = arith.constant 2 : index +// CHECK: %[[VAL_3:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_4:.*]] = fir.shape %[[VAL_3]] : (index) -> !fir.shape<1> +// CHECK: %[[VAL_5:.*]] = hlfir.elemental %[[VAL_4]] unordered : (!fir.shape<1>) -> !hlfir.expr<3xf32> { +// CHECK: ^bb0(%[[VAL_6:.*]]: index): +// CHECK: %[[VAL_9:.*]] = fir.do_loop %[[VAL_10:.*]] = %[[VAL_8]] to %[[VAL_2]] step %[[VAL_8]] unordered iter_args(%[[VAL_11:.*]] = %[[VAL_7]]) -> (f32) { +// CHECK: %[[VAL_12:.*]] = hlfir.apply %[[VAL_0]], %[[VAL_10]], %[[VAL_6]] : (!hlfir.expr<2x3xf32>, index, index) -> f32 +// CHECK: %[[VAL_13:.*]] = arith.addf %[[VAL_11]], %[[VAL_12]] fastmath : f32 +// CHECK: fir.result %[[VAL_13]] : f32 +// CHECK: } +// CHECK: hlfir.yield_element %[[VAL_9]] : f32 +// CHECK: } +// CHECK: return +// CHECK: } + +// total 1d reduction +func.func @sum_total_1d_reduction(%arg0: !fir.box>) -> i32 { + %cst = arith.constant 1 : i32 + %res = hlfir.sum %arg0 dim %cst : (!fir.box>, i32) -> i32 + return %res : i32 +} +// CHECK-LABEL: func.func @sum_total_1d_reduction( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>) -> i32 { +// CHECK: %[[VAL_8:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_2:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_3:.*]] = arith.constant 0 : i32 +// CHECK: %[[VAL_4:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_5:.*]] = fir.do_loop %[[VAL_6:.*]] = %[[VAL_4]] to %[[VAL_2]] step %[[VAL_4]] unordered iter_args(%[[VAL_7:.*]] = %[[VAL_3]]) -> (i32) { +// CHECK: %[[VAL_9:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_8]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_11:.*]] = arith.subi %[[VAL_9]]#0, %[[VAL_4]] : index +// CHECK: %[[VAL_12:.*]] = arith.addi %[[VAL_6]], %[[VAL_11]] : index +// CHECK: %[[VAL_13:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_12]]) : (!fir.box>, index) -> !fir.ref +// CHECK: %[[VAL_14:.*]] = fir.load %[[VAL_13]] : !fir.ref +// CHECK: %[[VAL_15:.*]] = arith.addi %[[VAL_7]], %[[VAL_14]] : i32 +// CHECK: fir.result %[[VAL_15]] : i32 +// CHECK: } +// CHECK: return +// CHECK: } + +// total 2d reduction +func.func @sum_total_2d_reduction(%arg0: !fir.box>) -> i32 { + %res = hlfir.sum %arg0 : (!fir.box>) -> i32 + return %res : i32 +} +// CHECK-LABEL: func.func @sum_total_2d_reduction( +// CHECK-SAME: %[[VAL_0:.*]]: !fir.box>) -> i32 { +// CHECK: %[[VAL_5:.*]] = arith.constant 1 : index +// CHECK: %[[VAL_4:.*]] = arith.constant 0 : i32 +// CHECK: %[[VAL_3:.*]] = arith.constant 3 : index +// CHECK: %[[VAL_1:.*]] = arith.constant 0 : index +// CHECK: %[[VAL_2:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_1]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_6:.*]] = fir.do_loop %[[VAL_7:.*]] = %[[VAL_5]] to %[[VAL_3]] step %[[VAL_5]] unordered iter_args(%[[VAL_8:.*]] = %[[VAL_4]]) -> (i32) { +// CHECK: %[[VAL_9:.*]] = fir.do_loop %[[VAL_10:.*]] = %[[VAL_5]] to %[[VAL_2]]#1 step %[[VAL_5]] unordered iter_args(%[[VAL_11:.*]] = %[[VAL_8]]) -> (i32) { +// CHECK: %[[VAL_13:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_1]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_15:.*]]:3 = fir.box_dims %[[VAL_0]], %[[VAL_5]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[VAL_17:.*]] = arith.subi %[[VAL_13]]#0, %[[VAL_5]] : index +// CHECK: %[[VAL_18:.*]] = arith.addi %[[VAL_10]], %[[VAL_17]] : index +// CHECK: %[[VAL_19:.*]] = arith.subi %[[VAL_15]]#0, %[[VAL_5]] : index +// CHECK: %[[VAL_20:.*]] = arith.addi %[[VAL_7]], %[[VAL_19]] : index +// CHECK: %[[VAL_21:.*]] = hlfir.designate %[[VAL_0]] (%[[VAL_18]], %[[VAL_20]]) : (!fir.box>, index, index) -> !fir.ref +// CHECK: %[[VAL_22:.*]] = fir.load %[[VAL_21]] : !fir.ref +// CHECK: %[[VAL_23:.*]] = arith.addi %[[VAL_11]], %[[VAL_22]] : i32 +// CHECK: fir.result %[[VAL_23]] : i32 +// CHECK: } +// CHECK: fir.result %[[VAL_9]] : i32 +// CHECK: } +// CHECK: return +// CHECK: } + +// negative: invalid dim==0 +func.func @sum_invalid_dim0(%arg0: !hlfir.expr<2x3xi32>) -> !hlfir.expr<3xi32> { + %cst = arith.constant 0 : i32 + %res = hlfir.sum %arg0 dim %cst : (!hlfir.expr<2x3xi32>, i32) -> !hlfir.expr<3xi32> + return %res : !hlfir.expr<3xi32> +} +// CHECK-LABEL: func.func @sum_invalid_dim0( +// CHECK: hlfir.sum %{{.*}} dim %{{.*}} : (!hlfir.expr<2x3xi32>, i32) -> !hlfir.expr<3xi32> + +// negative: invalid dim>rank +func.func @sum_invalid_dim_big(%arg0: !hlfir.expr<2x3xi32>) -> !hlfir.expr<3xi32> { + %cst = arith.constant 3 : i32 + %res = hlfir.sum %arg0 dim %cst : (!hlfir.expr<2x3xi32>, i32) -> !hlfir.expr<3xi32> + return %res : !hlfir.expr<3xi32> +} +// CHECK-LABEL: func.func @sum_invalid_dim_big( +// CHECK: hlfir.sum %{{.*}} dim %{{.*}} : (!hlfir.expr<2x3xi32>, i32) -> !hlfir.expr<3xi32> diff --git a/flang/test/HLFIR/simplify-hlfir-intrinsics.fir b/flang/test/HLFIR/simplify-hlfir-intrinsics.fir index aeea8bfc97326..5fd21e98a8d87 100644 --- a/flang/test/HLFIR/simplify-hlfir-intrinsics.fir +++ b/flang/test/HLFIR/simplify-hlfir-intrinsics.fir @@ -1,25 +1,23 @@ // RUN: fir-opt --simplify-hlfir-intrinsics %s | FileCheck %s // box with known extents -func.func @transpose0(%arg0: !fir.box>) { +func.func @transpose0(%arg0: !fir.box>) -> !hlfir.expr<2x1xi32> { %res = hlfir.transpose %arg0 : (!fir.box>) -> !hlfir.expr<2x1xi32> - return + return %res : !hlfir.expr<2x1xi32> } // CHECK-LABEL: func.func @transpose0( -// CHECK-SAME: %[[ARG0:.*]]: !fir.box>) { +// CHECK-SAME: %[[ARG0:.*]]: !fir.box>) -> !hlfir.expr<2x1xi32> { +// CHECK: %[[C0:.*]] = arith.constant 0 : index // CHECK: %[[C1:.*]] = arith.constant 1 : index // CHECK: %[[C2:.*]] = arith.constant 2 : index // CHECK: %[[SHAPE:.*]] = fir.shape %[[C2]], %[[C1]] : (index, index) -> !fir.shape<2> // CHECK: %[[EXPR:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x1xi32> { // CHECK: ^bb0(%[[I:.*]]: index, %[[J:.*]]: index): -// CHECK: %[[C0:.*]] = arith.constant 0 : index // CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[C1_1:.*]] = arith.constant 1 : index -// CHECK: %[[DIMS1:.*]]:3 = fir.box_dims %[[ARG0]], %[[C1_1]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[C1_2:.*]] = arith.constant 1 : index -// CHECK: %[[LOWER_BOUND0:.*]] = arith.subi %[[DIMS0]]#0, %[[C1_2]] : index +// CHECK: %[[DIMS1:.*]]:3 = fir.box_dims %[[ARG0]], %[[C1]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[LOWER_BOUND0:.*]] = arith.subi %[[DIMS0]]#0, %[[C1]] : index // CHECK: %[[J_OFFSET:.*]] = arith.addi %[[J]], %[[LOWER_BOUND0]] : index -// CHECK: %[[LOWER_BOUND1:.*]] = arith.subi %[[DIMS1]]#0, %[[C1_2]] : index +// CHECK: %[[LOWER_BOUND1:.*]] = arith.subi %[[DIMS1]]#0, %[[C1]] : index // CHECK: %[[I_OFFSET:.*]] = arith.addi %[[I]], %[[LOWER_BOUND1]] : index // CHECK: %[[ELEMENT_REF:.*]] = hlfir.designate %[[ARG0]] (%[[J_OFFSET]], %[[I_OFFSET]]) : (!fir.box>, index, index) -> !fir.ref // CHECK: %[[ELEMENT:.*]] = fir.load %[[ELEMENT_REF]] : !fir.ref @@ -29,12 +27,12 @@ func.func @transpose0(%arg0: !fir.box>) { // CHECK: } // expr with known extents -func.func @transpose1(%arg0: !hlfir.expr<1x2xi32>) { +func.func @transpose1(%arg0: !hlfir.expr<1x2xi32>) -> !hlfir.expr<2x1xi32> { %res = hlfir.transpose %arg0 : (!hlfir.expr<1x2xi32>) -> !hlfir.expr<2x1xi32> - return + return %res : !hlfir.expr<2x1xi32> } // CHECK-LABEL: func.func @transpose1( -// CHECK-SAME: %[[ARG0:.*]]: !hlfir.expr<1x2xi32>) { +// CHECK-SAME: %[[ARG0:.*]]: !hlfir.expr<1x2xi32>) -> !hlfir.expr<2x1xi32> { // CHECK: %[[C1:.*]] = arith.constant 1 : index // CHECK: %[[C2:.*]] = arith.constant 2 : index // CHECK: %[[SHAPE:.*]] = fir.shape %[[C2]], %[[C1]] : (index, index) -> !fir.shape<2> @@ -47,26 +45,24 @@ func.func @transpose1(%arg0: !hlfir.expr<1x2xi32>) { // CHECK: } // box with unknown extent -func.func @transpose2(%arg0: !fir.box>) { +func.func @transpose2(%arg0: !fir.box>) -> !hlfir.expr<2x?xi32> { %res = hlfir.transpose %arg0 : (!fir.box>) -> !hlfir.expr<2x?xi32> - return + return %res : !hlfir.expr<2x?xi32> } // CHECK-LABEL: func.func @transpose2( -// CHECK-SAME: %[[ARG0:.*]]: !fir.box>) { +// CHECK-SAME: %[[ARG0:.*]]: !fir.box>) -> !hlfir.expr<2x?xi32> { +// CHECK: %[[C1:.*]] = arith.constant 1 : index +// CHECK: %[[C2:.*]] = arith.constant 2 : index // CHECK: %[[C0:.*]] = arith.constant 0 : index // CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[C2:.*]] = arith.constant 2 : index // CHECK: %[[SHAPE:.*]] = fir.shape %[[C2]], %[[DIMS0]]#1 : (index, index) -> !fir.shape<2> // CHECK: %[[EXPR:.*]] = hlfir.elemental %[[SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x?xi32> { // CHECK: ^bb0(%[[I:.*]]: index, %[[J:.*]]: index): -// CHECK: %[[C0_1:.*]] = arith.constant 0 : index -// CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0_1]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[C1_1:.*]] = arith.constant 1 : index -// CHECK: %[[DIMS1_1:.*]]:3 = fir.box_dims %[[ARG0]], %[[C1_1]] : (!fir.box>, index) -> (index, index, index) -// CHECK: %[[C1_2:.*]] = arith.constant 1 : index -// CHECK: %[[LOWER_BOUND0:.*]] = arith.subi %[[DIMS0]]#0, %[[C1_2]] : index +// CHECK: %[[DIMS0:.*]]:3 = fir.box_dims %[[ARG0]], %[[C0]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[DIMS1_1:.*]]:3 = fir.box_dims %[[ARG0]], %[[C1]] : (!fir.box>, index) -> (index, index, index) +// CHECK: %[[LOWER_BOUND0:.*]] = arith.subi %[[DIMS0]]#0, %[[C1]] : index // CHECK: %[[J_OFFSET:.*]] = arith.addi %[[J]], %[[LOWER_BOUND0]] : index -// CHECK: %[[LOWER_BOUND1:.*]] = arith.subi %[[DIMS1_1]]#0, %[[C1_2]] : index +// CHECK: %[[LOWER_BOUND1:.*]] = arith.subi %[[DIMS1_1]]#0, %[[C1]] : index // CHECK: %[[I_OFFSET:.*]] = arith.addi %[[I]], %[[LOWER_BOUND1]] : index // CHECK: %[[ELE_REF:.*]] = hlfir.designate %[[ARG0]] (%[[J_OFFSET]], %[[I_OFFSET]]) : (!fir.box>, index, index) -> !fir.ref // CHECK: %[[ELEMENT:.*]] = fir.load %[[ELE_REF]] : !fir.ref @@ -76,15 +72,15 @@ func.func @transpose2(%arg0: !fir.box>) { // CHECK: } // expr with unknown extent -func.func @transpose3(%arg0: !hlfir.expr) { +func.func @transpose3(%arg0: !hlfir.expr) -> !hlfir.expr<2x?xi32> { %res = hlfir.transpose %arg0 : (!hlfir.expr) -> !hlfir.expr<2x?xi32> - return + return %res : !hlfir.expr<2x?xi32> } // CHECK-LABEL: func.func @transpose3( -// CHECK-SAME: %[[ARG0:.*]]: !hlfir.expr) { +// CHECK-SAME: %[[ARG0:.*]]: !hlfir.expr) -> !hlfir.expr<2x?xi32> { +// CHECK: %[[C2:.*]] = arith.constant 2 : index // CHECK: %[[IN_SHAPE:.*]] = hlfir.shape_of %[[ARG0]] : (!hlfir.expr) -> !fir.shape<2> // CHECK: %[[EXTENT0:.*]] = hlfir.get_extent %[[IN_SHAPE]] {dim = 0 : index} : (!fir.shape<2>) -> index -// CHECK: %[[C2:.*]] = arith.constant 2 : index // CHECK: %[[OUT_SHAPE:.*]] = fir.shape %[[C2]], %[[EXTENT0]] : (index, index) -> !fir.shape<2> // CHECK: %[[EXPR:.*]] = hlfir.elemental %[[OUT_SHAPE]] unordered : (!fir.shape<2>) -> !hlfir.expr<2x?xi32> { // CHECK: ^bb0(%[[I:.*]]: index, %[[J:.*]]: index): @@ -118,8 +114,7 @@ func.func @transpose4(%arg0: !hlfir.expr<2x2xf32>, %arg1: !fir.ref, index, index) -> f32 // CHECK: hlfir.yield_element %[[ELE]] : f32 // CHECK: } -// CHECK: %[[SHAPE1:.*]] = hlfir.shape_of %[[TRANSPOSE]] : (!hlfir.expr<2x2xf32>) -> !fir.shape<2> -// CHECK: %[[COS:.*]] = hlfir.elemental %[[SHAPE1]] : (!fir.shape<2>) -> !hlfir.expr<2x2xf32> { +// CHECK: %[[COS:.*]] = hlfir.elemental %[[SHAPE0]] : (!fir.shape<2>) -> !hlfir.expr<2x2xf32> { // CHECK: ^bb0(%[[I:.*]]: index, %[[J:.*]]: index): // CHECK: %[[ELE:.*]] = hlfir.apply %[[TRANSPOSE]], %[[I]], %[[J]] : (!hlfir.expr<2x2xf32>, index, index) -> f32 // CHECK: %[[COS_ELE:.*]] = math.cos %[[ELE]] fastmath : f32 @@ -170,14 +165,13 @@ func.func @transpose5(%arg0: !fir.ref>, !fir. } // CHECK-LABEL: func.func @transpose5( // ... -// CHECK: %[[TRANSPOSE:.*]] = hlfir.elemental %[[SHAPE0:.*]] +// CHECK: %[[TRANSPOSE:.*]] = hlfir.elemental %[[SHAPE0:[A-Za-z._]*]] // CHECK: ^bb0(%[[I:.*]]: index, %[[J:.*]]: index): // CHECK: %[[ELE:.*]] = hlfir.designate %[[ARRAY:.*]] (%[[J]], %[[I]]) // CHECK: %[[LOAD:.*]] = fir.load %[[ELE]] // CHECK: hlfir.yield_element %[[LOAD]] // CHECK: } -// CHECK: %[[SHAPE1:.*]] = hlfir.shape_of %[[TRANSPOSE]] -// CHECK: %[[COS:.*]] = hlfir.elemental %[[SHAPE1]] +// CHECK: %[[COS:.*]] = hlfir.elemental %[[SHAPE0]] // ... // CHECK: hlfir.assign %[[COS]] to %{{.*}} realloc // CHECK: hlfir.destroy %[[COS]] diff --git a/flang/test/Integration/OpenMP/workshare-axpy.f90 b/flang/test/Integration/OpenMP/workshare-axpy.f90 index 0c4524f855290..12246e54d3432 100644 --- a/flang/test/Integration/OpenMP/workshare-axpy.f90 +++ b/flang/test/Integration/OpenMP/workshare-axpy.f90 @@ -13,7 +13,7 @@ subroutine sb1(a, x, y, z) integer :: a integer :: x(:) integer :: y(:) - integer :: z(:) + integer, allocatable :: z(:) !$omp parallel workshare z = a * x + y !$omp end parallel workshare @@ -43,7 +43,7 @@ subroutine sb1(a, x, y, z) ! FIR: func.func @_QPsb1 ! FIR: omp.parallel { -! FIR: omp.single copyprivate(%9 -> @_workshare_copy_i32 : !fir.ref, %10 -> @_workshare_copy_heap_Uxi32 : !fir.ref>>) { +! FIR: omp.single copyprivate(%{{[a-z0-9]+}} -> @_workshare_copy_i32 : !fir.ref, %{{[a-z0-9]+}} -> @_workshare_copy_heap_Uxi32 : !fir.ref>>) { ! FIR: fir.allocmem ! FIR: omp.wsloop { ! FIR: omp.loop_nest diff --git a/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf b/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf index aac569b6eb35b..09aefc055e6fa 100644 --- a/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf +++ b/flang/test/Lower/CUDA/cuda-kernel-loop-directive.cuf @@ -98,3 +98,18 @@ end subroutine ! CHECK-LABEL: func.func @_QPsub2 ! CHECK: cuf.kernel + +subroutine sub3() + integer, device :: a(10), b(10) + integer :: lb = 1 + integer :: n = 10 + integer :: s = 1 + + !$cuf kernel do <<< *, * >>> + do i = lb, n, s + a(i) = a(i) * b(i) + end do +end + +! CHECK-LABEL: func.func @_QPsub3 +! CHECK: cuf.kernel diff --git a/flang/test/Lower/CUDA/cuda-program-global.cuf b/flang/test/Lower/CUDA/cuda-program-global.cuf index 90b401c9ba6a5..a21fc06537f75 100644 --- a/flang/test/Lower/CUDA/cuda-program-global.cuf +++ b/flang/test/Lower/CUDA/cuda-program-global.cuf @@ -7,6 +7,7 @@ program test integer, device :: a(10) integer, unified :: u(10) integer, allocatable, pinned :: p(:) + real, device, target :: t(10) integer :: b(10) integer :: i print*,i @@ -18,6 +19,7 @@ end ! CHECK: %[[ALLOCA:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFEi"} ! CHECK: hlfir.declare %[[ALLOCA]] {uniq_name = "_QFEi"} : (!fir.ref) -> (!fir.ref, !fir.ref) ! CHECK: cuf.alloc !fir.box>> {bindc_name = "p", data_attr = #cuf.cuda, uniq_name = "_QFEp"} -> !fir.ref>>> +! CHECK: cuf.alloc !fir.array<10xf32> {bindc_name = "t", data_attr = #cuf.cuda, uniq_name = "_QFEt"} -> !fir.ref> ! CHECK-NOT: fir.global internal @_QFEa {data_attr = #cuf.cuda} : !fir.array<10xi32> {{{$}} ! CHECK: fir.global internal @_QFEb : !fir.array<10xi32> {{{$}} diff --git a/flang/test/Lower/HLFIR/array-ctor-as-runtime-temp.f90 b/flang/test/Lower/HLFIR/array-ctor-as-runtime-temp.f90 index e1e65fc48baba..727eff7613e48 100644 --- a/flang/test/Lower/HLFIR/array-ctor-as-runtime-temp.f90 +++ b/flang/test/Lower/HLFIR/array-ctor-as-runtime-temp.f90 @@ -17,12 +17,11 @@ subroutine test_loops() ! CHECK: fir.store %[[VAL_6]] to %[[VAL_2]] : !fir.ref>>> ! CHECK: %[[VAL_7:.*]] = arith.constant false ! CHECK: %[[VAL_8:.*]] = fir.convert %[[VAL_1]] : (!fir.ref>) -> !fir.llvm_ptr -! CHECK: %[[VAL_9:.*]] = arith.constant 80 : i32 ! CHECK: %[[VAL_10:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref> ! CHECK: %[[VAL_11:.*]] = arith.constant 7 : i32 ! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_2]] : (!fir.ref>>>) -> !fir.ref> ! CHECK: %[[VAL_13:.*]] = fir.convert %[[VAL_10]] : (!fir.ref>) -> !fir.ref -! CHECK: %[[VAL_14:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_8]], %[[VAL_12]], %[[VAL_7]], %[[VAL_9]], %[[VAL_13]], %[[VAL_11]]) fastmath : (!fir.llvm_ptr, !fir.ref>, i1, i32, !fir.ref, i32) -> none +! CHECK: %[[VAL_14:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_8]], %[[VAL_12]], %[[VAL_7]], %[[VAL_13]], %[[VAL_11]]) fastmath : (!fir.llvm_ptr, !fir.ref>, i1, !fir.ref, i32) -> none ! CHECK: %[[VAL_15:.*]] = arith.constant 1 : i64 ! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_15]] : (i64) -> index ! CHECK: %[[VAL_17:.*]] = fir.call @_QMarrayctorPibar() fastmath : () -> i32 @@ -86,7 +85,7 @@ subroutine test_arrays(a) ! CHECK: %[[VAL_26:.*]] = arith.constant false ! CHECK: %[[VAL_27:.*]] = fir.convert %[[VAL_1]] : (!fir.ref>) -> !fir.llvm_ptr ! CHECK: %[[VAL_31:.*]] = fir.convert %[[VAL_2]] : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[VAL_33:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_27]], %[[VAL_31]], %[[VAL_26]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.llvm_ptr, !fir.ref>, i1, i32, !fir.ref, i32) -> none +! CHECK: %[[VAL_33:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_27]], %[[VAL_31]], %[[VAL_26]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.llvm_ptr, !fir.ref>, i1, !fir.ref, i32) -> none ! CHECK: %[[VAL_34:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.box>) -> !fir.box ! CHECK: %[[VAL_35:.*]] = fir.call @_FortranAPushArrayConstructorValue(%[[VAL_27]], %[[VAL_34]]) {{.*}}: (!fir.llvm_ptr, !fir.box) -> none ! CHECK: %[[VAL_36:.*]] = fir.convert %[[VAL_3]]#1 : (!fir.box>) -> !fir.box @@ -107,7 +106,7 @@ subroutine test_arrays_unpredictable_size() ! CHECK: %[[VAL_9:.*]] = arith.constant false ! CHECK: %[[VAL_10:.*]] = fir.convert %[[VAL_3]] : (!fir.ref>) -> !fir.llvm_ptr ! CHECK: %[[VAL_14:.*]] = fir.convert %[[VAL_4]] : (!fir.ref>>>) -> !fir.ref> -! CHECK: %[[VAL_16:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_10]], %[[VAL_14]], %[[VAL_9]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.llvm_ptr, !fir.ref>, i1, i32, !fir.ref, i32) -> none +! CHECK: %[[VAL_16:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_10]], %[[VAL_14]], %[[VAL_9]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.llvm_ptr, !fir.ref>, i1, !fir.ref, i32) -> none ! CHECK: fir.call @_QMarrayctorPrank1() {{.*}}: () -> !fir.box>> ! CHECK: %[[VAL_21:.*]] = fir.call @_FortranAPushArrayConstructorValue(%[[VAL_10]], %{{.*}}) {{.*}}: (!fir.llvm_ptr, !fir.box) -> none ! CHECK: fir.call @_QMarrayctorPrank3() {{.*}}: () -> !fir.box>> diff --git a/flang/test/Lower/HLFIR/array-ctor-character.f90 b/flang/test/Lower/HLFIR/array-ctor-character.f90 index 881085b370ffe..7cbad5218f588 100644 --- a/flang/test/Lower/HLFIR/array-ctor-character.f90 +++ b/flang/test/Lower/HLFIR/array-ctor-character.f90 @@ -52,7 +52,7 @@ subroutine test_dynamic_length() ! CHECK: %[[VAL_15:.*]] = arith.constant true ! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_2]] : (!fir.ref>) -> !fir.llvm_ptr ! CHECK: %[[VAL_20:.*]] = fir.convert %[[VAL_3]] : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[VAL_22:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_16]], %[[VAL_20]], %[[VAL_15]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.llvm_ptr, !fir.ref>, i1, i32, !fir.ref, i32) -> none +! CHECK: %[[VAL_22:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_16]], %[[VAL_20]], %[[VAL_15]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.llvm_ptr, !fir.ref>, i1, !fir.ref, i32) -> none ! CHECK: fir.call @_QMchararrayctorPchar_pointer( ! CHECK: fir.call @_FortranAPushArrayConstructorValue(%[[VAL_16]], %{{.*}}) {{.*}}: (!fir.llvm_ptr, !fir.box) -> none ! CHECK: fir.call @_QMchararrayctorPchar_pointer( diff --git a/flang/test/Lower/HLFIR/array-ctor-derived.f90 b/flang/test/Lower/HLFIR/array-ctor-derived.f90 index 111225462a4bb..22f7fbd72cb59 100644 --- a/flang/test/Lower/HLFIR/array-ctor-derived.f90 +++ b/flang/test/Lower/HLFIR/array-ctor-derived.f90 @@ -28,7 +28,7 @@ subroutine test_simple(s1, s2) ! CHECK: %[[VAL_11:.*]] = arith.constant false ! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_2]] : (!fir.ref>) -> !fir.llvm_ptr ! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_3]] : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[VAL_18:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_12]], %[[VAL_16]], %[[VAL_11]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.llvm_ptr, !fir.ref>, i1, i32, !fir.ref, i32) -> none +! CHECK: %[[VAL_18:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_12]], %[[VAL_16]], %[[VAL_11]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.llvm_ptr, !fir.ref>, i1, !fir.ref, i32) -> none ! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_4]]#1 : (!fir.ref>) -> !fir.llvm_ptr ! CHECK: %[[VAL_20:.*]] = fir.call @_FortranAPushArrayConstructorSimpleScalar(%[[VAL_12]], %[[VAL_19]]) {{.*}}: (!fir.llvm_ptr, !fir.llvm_ptr) -> none ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_5]]#1 : (!fir.ref>) -> !fir.llvm_ptr @@ -56,7 +56,7 @@ subroutine test_with_polymorphic(s1, s2) ! CHECK: %[[VAL_11:.*]] = arith.constant false ! CHECK: %[[VAL_12:.*]] = fir.convert %[[VAL_2]] : (!fir.ref>) -> !fir.llvm_ptr ! CHECK: %[[VAL_16:.*]] = fir.convert %[[VAL_3]] : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %[[VAL_18:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_12]], %[[VAL_16]], %[[VAL_11]], %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.llvm_ptr, !fir.ref>, i1, i32, !fir.ref, i32) -> none +! CHECK: %[[VAL_18:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_12]], %[[VAL_16]], %[[VAL_11]], %{{.*}}, %{{.*}}) {{.*}}: (!fir.llvm_ptr, !fir.ref>, i1, !fir.ref, i32) -> none ! CHECK: %[[VAL_19A:.*]] = fir.box_addr %[[VAL_4]]#1 : (!fir.class>) -> !fir.ref> ! CHECK: %[[VAL_19:.*]] = fir.convert %[[VAL_19A]] : (!fir.ref>) -> !fir.llvm_ptr ! CHECK: %[[VAL_20:.*]] = fir.call @_FortranAPushArrayConstructorSimpleScalar(%[[VAL_12]], %[[VAL_19]]) {{.*}}: (!fir.llvm_ptr, !fir.llvm_ptr) -> none diff --git a/flang/test/Lower/HLFIR/cshift.f90 b/flang/test/Lower/HLFIR/cshift.f90 new file mode 100644 index 0000000000000..c3743068da4d7 --- /dev/null +++ b/flang/test/Lower/HLFIR/cshift.f90 @@ -0,0 +1,218 @@ +! Test lowering of CSHIFT intrinsic to HLFIR +! RUN: bbc -emit-hlfir -o - -I nowhere %s 2>&1 | FileCheck %s + +module types + type t + end type t +end module types + +! 1d shift by scalar +subroutine cshift1(a, s) + integer :: a(:), s + a = CSHIFT(a, 2) +end subroutine +! CHECK-LABEL: func.func @_QPcshift1( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "a"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref {fir.bindc_name = "s"}) { +! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] +! CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_6:.*]] = hlfir.cshift %[[VAL_3]]#0 %[[VAL_5]] : (!fir.box>, i32) -> !hlfir.expr +! CHECK: hlfir.assign %[[VAL_6]] to %[[VAL_3]]#0 : !hlfir.expr, !fir.box> +! CHECK: hlfir.destroy %[[VAL_6]] : !hlfir.expr +! CHECK: return +! CHECK: } + +! 1d shift by scalar with dim +subroutine cshift2(a, s) + integer :: a(:), s + a = CSHIFT(a, 2, 1) +end subroutine +! CHECK-LABEL: func.func @_QPcshift2( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "a"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref {fir.bindc_name = "s"}) { +! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] +! CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_6:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_7:.*]] = hlfir.cshift %[[VAL_3]]#0 %[[VAL_5]] dim %[[VAL_6]] : (!fir.box>, i32, i32) -> !hlfir.expr +! CHECK: hlfir.assign %[[VAL_7]] to %[[VAL_3]]#0 : !hlfir.expr, !fir.box> +! CHECK: hlfir.destroy %[[VAL_7]] : !hlfir.expr +! CHECK: return +! CHECK: } + +! 2d shift by scalar +subroutine cshift3(a, s) + integer :: a(:,:), s + a = CSHIFT(a, 2) +end subroutine +! CHECK-LABEL: func.func @_QPcshift3( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "a"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref {fir.bindc_name = "s"}) { +! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] +! CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_6:.*]] = hlfir.cshift %[[VAL_3]]#0 %[[VAL_5]] : (!fir.box>, i32) -> !hlfir.expr +! CHECK: hlfir.assign %[[VAL_6]] to %[[VAL_3]]#0 : !hlfir.expr, !fir.box> +! CHECK: hlfir.destroy %[[VAL_6]] : !hlfir.expr +! CHECK: return +! CHECK: } + +! 2d shift by scalar with dim +subroutine cshift4(a, s) + integer :: a(:,:), s + a = CSHIFT(a, 2, 2) +end subroutine +! CHECK-LABEL: func.func @_QPcshift4( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "a"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref {fir.bindc_name = "s"}) { +! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] +! CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_6:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_7:.*]] = hlfir.cshift %[[VAL_3]]#0 %[[VAL_5]] dim %[[VAL_6]] : (!fir.box>, i32, i32) -> !hlfir.expr +! CHECK: hlfir.assign %[[VAL_7]] to %[[VAL_3]]#0 : !hlfir.expr, !fir.box> +! CHECK: hlfir.destroy %[[VAL_7]] : !hlfir.expr +! CHECK: return +! CHECK: } + +! 2d shift by array +subroutine cshift5(a, s) + integer :: a(:,:), s(:) + a = CSHIFT(a, s) +end subroutine +! CHECK-LABEL: func.func @_QPcshift5( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "a"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.box> {fir.bindc_name = "s"}) { +! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] +! CHECK: %[[VAL_5:.*]] = hlfir.cshift %[[VAL_3]]#0 %[[VAL_4]]#0 : (!fir.box>, !fir.box>) -> !hlfir.expr +! CHECK: hlfir.assign %[[VAL_5]] to %[[VAL_3]]#0 : !hlfir.expr, !fir.box> +! CHECK: hlfir.destroy %[[VAL_5]] : !hlfir.expr +! CHECK: return +! CHECK: } + +! 2d shift by array expr +subroutine cshift6(a, s) + integer :: a(:,:), s(:) + a = CSHIFT(a, s + 1) +end subroutine +! CHECK-LABEL: func.func @_QPcshift6( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "a"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.box> {fir.bindc_name = "s"}) { +! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] +! CHECK: %[[VAL_5:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_6:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_7:.*]]:3 = fir.box_dims %[[VAL_4]]#0, %[[VAL_6]] : (!fir.box>, index) -> (index, index, index) +! CHECK: %[[VAL_8:.*]] = fir.shape %[[VAL_7]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[VAL_9:.*]] = hlfir.elemental %[[VAL_8]] unordered : (!fir.shape<1>) -> !hlfir.expr +! CHECK: %[[VAL_14:.*]] = hlfir.cshift %[[VAL_3]]#0 %[[VAL_9]] : (!fir.box>, !hlfir.expr) -> !hlfir.expr +! CHECK: hlfir.assign %[[VAL_14]] to %[[VAL_3]]#0 : !hlfir.expr, !fir.box> +! CHECK: hlfir.destroy %[[VAL_14]] : !hlfir.expr +! CHECK: hlfir.destroy %[[VAL_9]] : !hlfir.expr +! CHECK: return +! CHECK: } + +! 1d character(10,2) shift by scalar +subroutine cshift7(a, s) + character(10,2) :: a(:) + a = CSHIFT(a, 2) +end subroutine +! CHECK-LABEL: func.func @_QPcshift7( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>> {fir.bindc_name = "a"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref {fir.bindc_name = "s"}) { +! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_3:.*]] = arith.constant 10 : index +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]] +! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_1]] +! CHECK: %[[VAL_6:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_7:.*]] = hlfir.cshift %[[VAL_4]]#0 %[[VAL_6]] : (!fir.box>>, i32) -> !hlfir.expr> +! CHECK: hlfir.assign %[[VAL_7]] to %[[VAL_4]]#0 : !hlfir.expr>, !fir.box>> +! CHECK: hlfir.destroy %[[VAL_7]] : !hlfir.expr> +! CHECK: return +! CHECK: } + +! 1d character(*) shift by scalar +subroutine cshift8(a, s) + character(*) :: a(:) + a = CSHIFT(a, 2) +end subroutine +! CHECK-LABEL: func.func @_QPcshift8( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>> {fir.bindc_name = "a"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref {fir.bindc_name = "s"}) { +! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] +! CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_6:.*]] = hlfir.cshift %[[VAL_3]]#0 %[[VAL_5]] : (!fir.box>>, i32) -> !hlfir.expr> +! CHECK: hlfir.assign %[[VAL_6]] to %[[VAL_3]]#0 : !hlfir.expr>, !fir.box>> +! CHECK: hlfir.destroy %[[VAL_6]] : !hlfir.expr> +! CHECK: return +! CHECK: } + +! 1d type(t) shift by scalar +subroutine cshift9(a, s) + use types + type(t) :: a(:) + a = CSHIFT(a, 2) +end subroutine +! CHECK-LABEL: func.func @_QPcshift9( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box>> {fir.bindc_name = "a"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref {fir.bindc_name = "s"}) { +! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] +! CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_6:.*]] = hlfir.cshift %[[VAL_3]]#0 %[[VAL_5]] : (!fir.box>>, i32) -> !hlfir.expr> +! CHECK: hlfir.assign %[[VAL_6]] to %[[VAL_3]]#0 : !hlfir.expr>, !fir.box>> +! CHECK: hlfir.destroy %[[VAL_6]] : !hlfir.expr> +! CHECK: return +! CHECK: } + +! 1d class(t) shift by scalar +subroutine cshift10(a, s) + use types + class(t), allocatable :: a(:) + a = CSHIFT(a, 2) +end subroutine +! CHECK-LABEL: func.func @_QPcshift10( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>> {fir.bindc_name = "a"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref {fir.bindc_name = "s"}) { +! CHECK: %[[VAL_2:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_3:.*]]:2 = hlfir.declare %[[VAL_0]] +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_1]] +! CHECK: %[[VAL_5:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_3]]#0 : !fir.ref>>>> +! CHECK: %[[VAL_7:.*]] = hlfir.cshift %[[VAL_6]] %[[VAL_5]] : (!fir.class>>>, i32) -> !hlfir.expr?> +! CHECK: hlfir.assign %[[VAL_7]] to %[[VAL_3]]#0 realloc : !hlfir.expr?>, !fir.ref>>>> +! CHECK: hlfir.destroy %[[VAL_7]] : !hlfir.expr?> +! CHECK: return +! CHECK: } + +! 1d shift by scalar with variable dim +subroutine cshift11(a, s, d) + integer :: a(:), s, d + a = CSHIFT(a, 2, d) +end subroutine +! CHECK-LABEL: func.func @_QPcshift11( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.box> {fir.bindc_name = "a"}, +! CHECK-SAME: %[[VAL_1:.*]]: !fir.ref {fir.bindc_name = "s"}, +! CHECK-SAME: %[[VAL_2:.*]]: !fir.ref {fir.bindc_name = "d"}) { +! CHECK: %[[VAL_3:.*]] = fir.dummy_scope : !fir.dscope +! CHECK: %[[VAL_4:.*]]:2 = hlfir.declare %[[VAL_0]] dummy_scope %[[VAL_3]] {uniq_name = "_QFcshift11Ea"} : (!fir.box>, !fir.dscope) -> (!fir.box>, !fir.box>) +! CHECK: %[[VAL_5:.*]]:2 = hlfir.declare %[[VAL_2]] dummy_scope %[[VAL_3]] {uniq_name = "_QFcshift11Ed"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_6:.*]]:2 = hlfir.declare %[[VAL_1]] dummy_scope %[[VAL_3]] {uniq_name = "_QFcshift11Es"} : (!fir.ref, !fir.dscope) -> (!fir.ref, !fir.ref) +! CHECK: %[[VAL_7:.*]] = arith.constant 2 : i32 +! CHECK: %[[VAL_8:.*]] = fir.load %[[VAL_5]]#0 : !fir.ref +! CHECK: %[[VAL_9:.*]] = hlfir.cshift %[[VAL_4]]#0 %[[VAL_7]] dim %[[VAL_8]] : (!fir.box>, i32, i32) -> !hlfir.expr +! CHECK: hlfir.assign %[[VAL_9]] to %[[VAL_4]]#0 : !hlfir.expr, !fir.box> +! CHECK: hlfir.destroy %[[VAL_9]] : !hlfir.expr +! CHECK: return +! CHECK: } diff --git a/flang/test/Lower/HLFIR/goto-do-body.f90 b/flang/test/Lower/HLFIR/goto-do-body.f90 index 5e4bc2f3bc282..9e2c07f8fa292 100644 --- a/flang/test/Lower/HLFIR/goto-do-body.f90 +++ b/flang/test/Lower/HLFIR/goto-do-body.f90 @@ -40,7 +40,7 @@ subroutine sub1() ! CHECK: %[[TMP5:.*]] = arith.subi %[[TMP4]], %[[C1]] : i32 ! CHECK: fir.store %[[TMP5]] to %[[TRIP]] : !fir.ref ! CHECK: %[[TMP6:.*]] = fir.load %[[I]]#1 : !fir.ref -! CHECK: %[[TMP7:.*]] = arith.addi %[[TMP6]], %[[C1]] : i32 +! CHECK: %[[TMP7:.*]] = arith.addi %[[TMP6]], %[[C1]] overflow : i32 ! CHECK: fir.store %[[TMP7]] to %[[I]]#1 : !fir.ref ! CHECK: cf.br ^[[HEADER]] end do @@ -104,7 +104,7 @@ subroutine sub2() ! CHECK: fir.store %[[TMP9]] to %[[TRIP]] : !fir.ref ! CHECK: %[[TMP10:.*]] = fir.load %[[I]]#1 : !fir.ref ! CHECK: %[[STEP_VAL:.*]] = fir.load %[[STEP_VAR]] : !fir.ref -! CHECK: %[[TMP11:.*]] = arith.addi %[[TMP10]], %[[STEP_VAL]] : i32 +! CHECK: %[[TMP11:.*]] = arith.addi %[[TMP10]], %[[STEP_VAL]] overflow : i32 ! CHECK: fir.store %[[TMP11]] to %[[I]]#1 : !fir.ref ! CHECK: cf.br ^[[HEADER]] end do diff --git a/flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90 b/flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90 index 3f97a9f848d43..26d19c308feae 100644 --- a/flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90 +++ b/flang/test/Lower/HLFIR/poly_expr_for_nonpoly_dummy.f90 @@ -17,12 +17,9 @@ subroutine test1(x) call callee(cshift(x, 1)) end subroutine test1 ! CHECK-LABEL: func.func @_QPtest1( -! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {uniq_name = ".tmp.intrinsic_result"} : (!fir.class>>>, !fir.shift<1>) -> (!fir.class>>>, !fir.class>>>) -! CHECK: %[[VAL_22:.*]] = arith.constant true -! CHECK: %[[VAL_23:.*]] = hlfir.as_expr %[[VAL_21]]#0 move %[[VAL_22]] : (!fir.class>>>, i1) -> !hlfir.expr?> -! CHECK: %[[VAL_24:.*]] = arith.constant 0 : index -! CHECK: %[[VAL_25:.*]]:3 = fir.box_dims %[[VAL_21]]#0, %[[VAL_24]] : (!fir.class>>>, index) -> (index, index, index) -! CHECK: %[[VAL_26:.*]] = fir.shape %[[VAL_25]]#1 : (index) -> !fir.shape<1> +! CHECK: %[[VAL_4:.*]] = arith.constant 1 : i32 +! CHECK: %[[VAL_23:.*]] = hlfir.cshift %{{.*}} %[[VAL_4]] : (!fir.class>>, i32) -> !hlfir.expr?> +! CHECK: %[[VAL_26:.*]] = hlfir.shape_of %[[VAL_23]] : (!hlfir.expr?>) -> !fir.shape<1> ! CHECK: %[[VAL_27:.*]]:3 = hlfir.associate %[[VAL_23]](%[[VAL_26]]) {adapt.valuebyref} : (!hlfir.expr?>, !fir.shape<1>) -> (!fir.class>>>, !fir.class>>>, i1) ! CHECK: %[[VAL_28:.*]] = fir.rebox %[[VAL_27]]#0 : (!fir.class>>>) -> !fir.box>> ! CHECK: %[[VAL_29:.*]]:2 = hlfir.copy_in %[[VAL_28]] to %[[TMP_BOX:.*]] : (!fir.box>>, !fir.ref>>>>) -> (!fir.box>>, i1) diff --git a/flang/test/Lower/HLFIR/structure-constructor.f90 b/flang/test/Lower/HLFIR/structure-constructor.f90 index 41d08c14f5fa9..ed9ee5d0ac363 100644 --- a/flang/test/Lower/HLFIR/structure-constructor.f90 +++ b/flang/test/Lower/HLFIR/structure-constructor.f90 @@ -273,12 +273,11 @@ end subroutine test6 ! CHECK: fir.store %[[VAL_49]] to %[[VAL_4]] : !fir.ref}>>>>> ! CHECK: %[[VAL_50:.*]] = arith.constant false ! CHECK: %[[VAL_51:.*]] = fir.convert %[[VAL_3]] : (!fir.ref>) -> !fir.llvm_ptr -! CHECK: %[[VAL_52:.*]] = arith.constant 80 : i32 ! CHECK: %[[VAL_53:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref> ! CHECK: %[[VAL_54:.*]] = arith.constant {{[0-9]*}} : i32 ! CHECK: %[[VAL_55:.*]] = fir.convert %[[VAL_4]] : (!fir.ref}>>>>>) -> !fir.ref> ! CHECK: %[[VAL_56:.*]] = fir.convert %[[VAL_53]] : (!fir.ref>) -> !fir.ref -! CHECK: %[[VAL_57:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_51]], %[[VAL_55]], %[[VAL_50]], %[[VAL_52]], %[[VAL_56]], %[[VAL_54]]) fastmath : (!fir.llvm_ptr, !fir.ref>, i1, i32, !fir.ref, i32) -> none +! CHECK: %[[VAL_57:.*]] = fir.call @_FortranAInitArrayConstructorVector(%[[VAL_51]], %[[VAL_55]], %[[VAL_50]], %[[VAL_56]], %[[VAL_54]]) fastmath : (!fir.llvm_ptr, !fir.ref>, i1, !fir.ref, i32) -> none ! CHECK: %[[VAL_58:.*]]:2 = hlfir.declare %[[VAL_2]] {uniq_name = "ctor.temp"} : (!fir.ref}>>) -> (!fir.ref}>>, !fir.ref}>>) ! CHECK: %[[VAL_59:.*]] = fir.embox %[[VAL_58]]#0 : (!fir.ref}>>) -> !fir.box}>> ! CHECK: %[[VAL_60:.*]] = fir.address_of(@_QQclX{{.*}}) : !fir.ref> diff --git a/flang/test/Lower/OpenACC/acc-declare.f90 b/flang/test/Lower/OpenACC/acc-declare.f90 index 9fe51a8db55e3..0066e712fbdcc 100644 --- a/flang/test/Lower/OpenACC/acc-declare.f90 +++ b/flang/test/Lower/OpenACC/acc-declare.f90 @@ -469,6 +469,6 @@ subroutine init() end module ! CHECK-LABEL: func.func @_QMacc_declare_post_action_statPinit() -! CHECK: fir.call @_FortranAAllocatableAllocate({{.*}}) fastmath {acc.declare_action = #acc.declare_action} : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: fir.call @_FortranAAllocatableAllocate({{.*}}) fastmath {acc.declare_action = #acc.declare_action} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: fir.if -! CHECK: fir.call @_FortranAAllocatableAllocate({{.*}}) fastmath {acc.declare_action = #acc.declare_action} : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: fir.call @_FortranAAllocatableAllocate({{.*}}) fastmath {acc.declare_action = #acc.declare_action} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 diff --git a/flang/test/Lower/OpenMP/KernelLanguage/bare-clause.f90 b/flang/test/Lower/OpenMP/KernelLanguage/bare-clause.f90 new file mode 100644 index 0000000000000..1445c4fa225d2 --- /dev/null +++ b/flang/test/Lower/OpenMP/KernelLanguage/bare-clause.f90 @@ -0,0 +1,10 @@ +! RUN: %flang_fc1 -emit-hlfir -fopenmp -fopenmp-version=51 %s -o - | FileCheck %s + +program test + integer :: tmp + !$omp target teams ompx_bare num_teams(42) thread_limit(43) + tmp = 1 + !$omp end target teams +end program + +! CHECK: omp.target ompx_bare diff --git a/flang/test/Lower/OpenMP/Todo/atomic-compare-fail.f90 b/flang/test/Lower/OpenMP/Todo/atomic-compare-fail.f90 new file mode 100644 index 0000000000000..b82bd13622764 --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/atomic-compare-fail.f90 @@ -0,0 +1,11 @@ +! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s + +! CHECK: not yet implemented: OpenMP atomic compare +program p + integer :: x + logical :: r + !$omp atomic compare fail(relaxed) + if (x .eq. 0) then + x = 2 + end if +end program p diff --git a/flang/test/Lower/OpenMP/Todo/error.f90 b/flang/test/Lower/OpenMP/Todo/error.f90 new file mode 100644 index 0000000000000..b97e2c20a0cdf --- /dev/null +++ b/flang/test/Lower/OpenMP/Todo/error.f90 @@ -0,0 +1,7 @@ +! RUN: %not_todo_cmd %flang_fc1 -emit-fir -fopenmp -fopenmp-version=51 -o - %s 2>&1 | FileCheck %s + +! CHECK: not yet implemented: OpenMPErrorConstruct +program p + integer, allocatable :: x + !$omp error at(compilation) severity(warning) message("an error") +end program p diff --git a/flang/test/Lower/OpenMP/delayed-privatization-default-init.f90 b/flang/test/Lower/OpenMP/delayed-privatization-default-init.f90 new file mode 100644 index 0000000000000..0eeebe0afea54 --- /dev/null +++ b/flang/test/Lower/OpenMP/delayed-privatization-default-init.f90 @@ -0,0 +1,47 @@ +! Test delayed privatization for derived types with default initialization. + +! RUN: %flang_fc1 -emit-hlfir -fopenmp -mmlir --openmp-enable-delayed-privatization \ +! RUN: -o - %s 2>&1 | FileCheck %s +! RUN: bbc -emit-hlfir -fopenmp --openmp-enable-delayed-privatization -o - %s 2>&1 |\ +! RUN: FileCheck %s + +subroutine delayed_privatization_default_init + implicit none + type t + integer :: i = 2 + end type + integer :: i, res(4) + type(t) :: a + !$omp parallel private(a) + call do_something(a%i) + !$omp end parallel +end subroutine + +subroutine delayed_privatization_default_init_firstprivate + implicit none + type t + integer :: i = 2 + end type + integer :: i, res(4) + type(t) :: a + !$omp parallel firstprivate(a) + call do_something(a%i) + !$omp end parallel +end subroutine + +! CHECK-LABEL: omp.private {type = firstprivate} @_QFdelayed_privatization_default_init_firstprivateEa_firstprivate_ref_rec__QFdelayed_privatization_default_init_firstprivateTt : !fir.ref> alloc { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QFdelayed_privatization_default_init_firstprivateTt{i:i32}> {bindc_name = "a", pinned, uniq_name = "_QFdelayed_privatization_default_init_firstprivateEa"} +! CHECK-NEXT: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFdelayed_privatization_default_init_firstprivateEa"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: omp.yield(%[[VAL_9]]#0 : !fir.ref>) +! CHECK: } + +! CHECK-LABEL: omp.private {type = private} @_QFdelayed_privatization_default_initEa_private_ref_rec__QFdelayed_privatization_default_initTt : !fir.ref> alloc { +! CHECK: ^bb0(%[[VAL_0:.*]]: !fir.ref>): +! CHECK: %[[VAL_1:.*]] = fir.alloca !fir.type<_QFdelayed_privatization_default_initTt{i:i32}> {bindc_name = "a", pinned, uniq_name = "_QFdelayed_privatization_default_initEa"} +! CHECK: %[[VAL_2:.*]] = fir.embox %[[VAL_1]] : (!fir.ref>) -> !fir.box> +! CHECK: %[[VAL_6:.*]] = fir.convert %[[VAL_2]] : (!fir.box>) -> !fir.box +! CHECK: %[[VAL_8:.*]] = fir.call @_FortranAInitialize(%[[VAL_6]],{{.*}} +! CHECK-NEXT: %[[VAL_9:.*]]:2 = hlfir.declare %[[VAL_1]] {uniq_name = "_QFdelayed_privatization_default_initEa"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: omp.yield(%[[VAL_9]]#0 : !fir.ref>) +! CHECK: } diff --git a/flang/test/Lower/OpenMP/delayed-privatization-pointer.f90 b/flang/test/Lower/OpenMP/delayed-privatization-pointer.f90 index 796e4720c8c95..c96b0b49fd530 100644 --- a/flang/test/Lower/OpenMP/delayed-privatization-pointer.f90 +++ b/flang/test/Lower/OpenMP/delayed-privatization-pointer.f90 @@ -20,6 +20,9 @@ subroutine delayed_privatization_pointer ! CHECK-NEXT: ^bb0(%[[PRIV_ARG:.*]]: [[TYPE]]): ! CHECK-NEXT: %[[PRIV_ALLOC:.*]] = fir.alloca !fir.box> {bindc_name = "var1", pinned, uniq_name = "_QFdelayed_privatization_pointerEvar1"} +! CHECK-NEXT: %[[NULL:.*]] = fir.zero_bits !fir.ptr +! CHECK-NEXT: %[[INIT:.*]] = fir.embox %[[NULL]] : (!fir.ptr) -> !fir.box> +! CHECK-NEXT: fir.store %[[INIT]] to %[[PRIV_ALLOC]] : !fir.ref>> ! CHECK-NEXT: %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOC]] ! CHECK-NEXT: omp.yield(%[[PRIV_DECL]]#0 : [[TYPE]]) diff --git a/flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90 b/flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90 index 5e76e8ff1663b..99323e69113bc 100644 --- a/flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90 +++ b/flang/test/Lower/OpenMP/parallel-private-clause-fixes.f90 @@ -82,10 +82,10 @@ ! CHECK: %[[VAL_15:.*]] = fir.load %[[PRIV_J_DECL]]#0 : !fir.ref ! CHECK: %[[VAL_16:.*]] = arith.addi %[[LOAD]], %[[VAL_15]] : i32 ! CHECK: hlfir.assign %[[VAL_16]] to %[[PRIV_X_DECL]]#0 : i32, !fir.ref -! CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_13]], %[[VAL_11]] : index +! CHECK: %[[VAL_17:.*]] = arith.addi %[[VAL_13]], %[[VAL_11]] overflow : index ! CHECK: %[[STEPCAST:.*]] = fir.convert %[[VAL_11]] : (index) -> i32 ! CHECK: %[[IVLOAD:.*]] = fir.load %[[PRIV_J_DECL]]#1 : !fir.ref -! CHECK: %[[IVINC:.*]] = arith.addi %[[IVLOAD]], %[[STEPCAST]] +! CHECK: %[[IVINC:.*]] = arith.addi %[[IVLOAD]], %[[STEPCAST]] overflow : ! CHECK: fir.result %[[VAL_17]], %[[IVINC]] : index, i32 ! CHECK: } ! CHECK: fir.store %[[VAL_12]]#1 to %[[PRIV_J_DECL]]#1 : !fir.ref diff --git a/flang/test/Lower/OpenMP/private-derived-type.f90 b/flang/test/Lower/OpenMP/private-derived-type.f90 index af9a5b72e7175..9d680cd5d6114 100644 --- a/flang/test/Lower/OpenMP/private-derived-type.f90 +++ b/flang/test/Lower/OpenMP/private-derived-type.f90 @@ -28,14 +28,14 @@ end subroutine s4 ! CHECK: %[[VAL_15:.*]] = fir.call @_FortranAInitialize(%[[VAL_13]], %[[VAL_14]], %[[VAL_12]]) fastmath : (!fir.box, !fir.ref, i32) -> none ! CHECK: omp.parallel { ! CHECK: %[[VAL_23:.*]] = fir.alloca !fir.type<_QFs4Ty3{x:!fir.box>}> {bindc_name = "v", pinned, uniq_name = "_QFs4Ev"} -! CHECK: %[[VAL_24:.*]]:2 = hlfir.declare %[[VAL_23]] {uniq_name = "_QFs4Ev"} : (!fir.ref>}>>) -> (!fir.ref>}>>, !fir.ref>}>>) -! CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_24]]#1 : (!fir.ref>}>>) -> !fir.box>}>> +! CHECK: %[[VAL_25:.*]] = fir.embox %[[VAL_23]] : (!fir.ref>}>>) -> !fir.box>}>> ! CHECK: %[[VAL_26:.*]] = fir.address_of -! CHECK: %[[VAL_27:.*]] = arith.constant 4 : i32 +! CHECK: %[[VAL_27:.*]] = arith.constant 8 : i32 ! CHECK: %[[VAL_28:.*]] = fir.convert %[[VAL_25]] : (!fir.box>}>>) -> !fir.box ! CHECK: %[[VAL_29:.*]] = fir.convert %[[VAL_26]] : (!fir.ref>) -> !fir.ref ! Check we do call FortranAInitialize on the derived type ! CHECK: %[[VAL_30:.*]] = fir.call @_FortranAInitialize(%[[VAL_28]], %[[VAL_29]], %[[VAL_27]]) fastmath : (!fir.box, !fir.ref, i32) -> none +! CHECK: %[[VAL_24:.*]]:2 = hlfir.declare %[[VAL_23]] {uniq_name = "_QFs4Ev"} : (!fir.ref>}>>) -> (!fir.ref>}>>, !fir.ref>}>>) ! CHECK: omp.wsloop { ! CHECK: } ! CHECK: %[[VAL_39:.*]] = fir.embox %[[VAL_9]]#1 : (!fir.ref>}>>) -> !fir.box>}>> diff --git a/flang/test/Lower/OpenMP/target_private.f90 b/flang/test/Lower/OpenMP/target_private.f90 deleted file mode 100644 index 0b08fda8c574a..0000000000000 --- a/flang/test/Lower/OpenMP/target_private.f90 +++ /dev/null @@ -1,73 +0,0 @@ -!Test data-sharing attribute clauses for the `target` directive. - -!RUN: %flang_fc1 -emit-hlfir -fopenmp %s -o - | FileCheck %s - -!CHECK-LABEL: func.func @_QPomp_target_private() -subroutine omp_target_private - implicit none - integer :: x(1) - -!$omp target private(x) - x(1) = 42 -!$omp end target -!CHECK: omp.target { -!CHECK-DAG: %[[C1:.*]] = arith.constant 1 : index -!CHECK-DAG: %[[PRIV_ALLOC:.*]] = fir.alloca !fir.array<1xi32> {bindc_name = "x", -!CHECK-SAME: pinned, uniq_name = "_QFomp_target_privateEx"} -!CHECK-NEXT: %[[SHAPE:.*]] = fir.shape %[[C1]] : (index) -> !fir.shape<1> -!CHECK-NEXT: %[[PRIV_DECL:.*]]:2 = hlfir.declare %[[PRIV_ALLOC]](%[[SHAPE]]) -!CHECK-SAME: {uniq_name = "_QFomp_target_privateEx"} : -!CHECK-SAME: (!fir.ref>, !fir.shape<1>) -> -!CHECK-SAME: (!fir.ref>, !fir.ref>) -!CHECK-DAG: %[[C42:.*]] = arith.constant 42 : i32 -!CHECK-DAG: %[[C1_2:.*]] = arith.constant 1 : index -!CHECK-NEXT: %[[PRIV_BINDING:.*]] = hlfir.designate %[[PRIV_DECL]]#0 (%[[C1_2]]) -!CHECK-SAME: : (!fir.ref>, index) -> !fir.ref -!CHECK-NEXT: hlfir.assign %[[C42]] to %[[PRIV_BINDING]] : i32, !fir.ref -!CHECK-NEXT: omp.terminator -!CHECK-NEXT: } - -end subroutine omp_target_private - -!CHECK-LABEL: func.func @_QPomp_target_target_do_simd() -subroutine omp_target_target_do_simd() - implicit none - - real(8) :: var - integer(8) :: iv - -!$omp target teams distribute parallel do simd private(iv,var) - do iv=0,10 - var = 3.14 - end do -!$omp end target teams distribute parallel do simd - -!CHECK: %[[IV:.*]] = omp.map.info{{.*}}map_clauses(implicit{{.*}}{name = "iv"} -!CHECK: %[[VAR:.*]] = omp.map.info{{.*}}map_clauses(implicit{{.*}}{name = "var"} -!CHECK: omp.target -!CHECK-SAME: map_entries(%[[IV]] -> %[[MAP_IV:.*]], %[[VAR]] -> %[[MAP_VAR:.*]] : !fir.ref, !fir.ref) -!CHECK: %[[MAP_IV_DECL:.*]]:2 = hlfir.declare %[[MAP_IV]] -!CHECK: %[[MAP_VAR_DECL:.*]]:2 = hlfir.declare %[[MAP_VAR]] -!CHECK: omp.teams { -!CHECK: omp.parallel private(@{{.*}} %[[MAP_IV_DECL]]#0 -> %[[IV_PRIV:.*]], @{{.*}} %[[MAP_VAR_DECL]]#0 -> %[[VAR_PRIV:.*]] : !fir.ref, !fir.ref) { -!CHECK: %[[IV_DECL:.*]]:2 = hlfir.declare %[[IV_PRIV]] -!CHECK: %[[VAR_DECL:.*]]:2 = hlfir.declare %[[VAR_PRIV]] -!CHECK: omp.distribute { -!CHECK-NEXT: omp.wsloop { -!CHECK-NEXT: omp.simd { -!CHECK-NEXT: omp.loop_nest -!CHECK: fir.store {{.*}} to %[[IV_DECL]]#1 -!CHECK: hlfir.assign {{.*}} to %[[VAR_DECL]]#0 -!CHECK: omp.yield -!CHECK-NEXT: } -!CHECK-NEXT: } {omp.composite} -!CHECK-NEXT: } {omp.composite} -!CHECK-NEXT: } {omp.composite} -!CHECK-NEXT: omp.terminator -!CHECK-NEXT: } -!CHECK-NEXT: omp.terminator -!CHECK-NEXT: } -!CHECK-NEXT: omp.terminator -!CHECK-NEXT: } - -end subroutine omp_target_target_do_simd diff --git a/flang/test/Lower/OpenMP/Todo/task_detach.f90 b/flang/test/Lower/OpenMP/task_detach.f90 similarity index 57% rename from flang/test/Lower/OpenMP/Todo/task_detach.f90 rename to flang/test/Lower/OpenMP/task_detach.f90 index cb6943073d4b3..f943abe6c591a 100644 --- a/flang/test/Lower/OpenMP/Todo/task_detach.f90 +++ b/flang/test/Lower/OpenMP/task_detach.f90 @@ -1,12 +1,14 @@ ! REQUIRES: openmp_runtime -! RUN: %not_todo_cmd bbc -emit-fir %openmp_flags -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s -! RUN: %not_todo_cmd %flang_fc1 -emit-fir %openmp_flags -fopenmp -fopenmp-version=50 -o - %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -emit-fir %openmp_flags -fopenmp -fopenmp-version=50 -o - %s | FileCheck %s !=============================================================================== ! `detach` clause !=============================================================================== -! CHECK: not yet implemented: DETACH clause is not implemented yet +!CHECK: omp.task detach(%[[EVENT_HANDLE:.*]] : !fir.ref) { +!CHECK: fir.call @_QPfoo() fastmath : () -> () +!CHECK: omp.terminator +!CHECK: } subroutine omp_task_detach() use omp_lib integer (kind=omp_event_handle_kind) :: event diff --git a/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90 b/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90 index a49eba69ff38c..ce45d09d77a22 100644 --- a/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90 +++ b/flang/test/Lower/OpenMP/wsloop-reduction-allocatable-array-minmax.f90 @@ -206,10 +206,10 @@ program reduce15 ! CHECK: %[[VAL_48:.*]] = fir.convert %[[VAL_47]] : (i32) -> i64 ! CHECK: %[[VAL_49:.*]] = hlfir.designate %[[VAL_46]] (%[[VAL_48]]) : (!fir.box>>, i64) -> !fir.ref ! CHECK: hlfir.assign %[[VAL_45]] to %[[VAL_49]] : i32, !fir.ref -! CHECK: %[[VAL_50:.*]] = arith.addi %[[VAL_43]], %[[VAL_40]] : index +! CHECK: %[[VAL_50:.*]] = arith.addi %[[VAL_43]], %[[VAL_40]] overflow : index ! CHECK: %[[VAL_51:.*]] = fir.convert %[[VAL_40]] : (index) -> i32 ! CHECK: %[[VAL_52:.*]] = fir.load %[[VAL_3]]#1 : !fir.ref -! CHECK: %[[VAL_53:.*]] = arith.addi %[[VAL_52]], %[[VAL_51]] : i32 +! CHECK: %[[VAL_53:.*]] = arith.addi %[[VAL_52]], %[[VAL_51]] overflow : i32 ! CHECK: fir.result %[[VAL_50]], %[[VAL_53]] : index, i32 ! CHECK: } ! CHECK: fir.store %[[VAL_54:.*]]#1 to %[[VAL_3]]#1 : !fir.ref diff --git a/flang/test/Lower/OpenMP/wsloop-variable.f90 b/flang/test/Lower/OpenMP/wsloop-variable.f90 index 8d235c10fa1d6..cc77ce754d97e 100644 --- a/flang/test/Lower/OpenMP/wsloop-variable.f90 +++ b/flang/test/Lower/OpenMP/wsloop-variable.f90 @@ -150,10 +150,10 @@ subroutine wsloop_variable_sub !CHECK: %[[VAL_42:.*]] = arith.addi %[[VAL_40]], %[[VAL_41]] : i64 !CHECK: %[[VAL_43:.*]] = fir.convert %[[VAL_42]] : (i64) -> f32 !CHECK: hlfir.assign %[[VAL_43]] to %[[VAL_21]]#0 : f32, !fir.ref -!CHECK: %[[VAL_44:.*]] = arith.addi %[[VAL_37]], %[[VAL_34]] : index +!CHECK: %[[VAL_44:.*]] = arith.addi %[[VAL_37]], %[[VAL_34]] overflow : index !CHECK: %[[VAL_45:.*]] = fir.convert %[[VAL_34]] : (index) -> i64 !CHECK: %[[VAL_46:.*]] = fir.load %[[VAL_17]]#1 : !fir.ref -!CHECK: %[[VAL_47:.*]] = arith.addi %[[VAL_46]], %[[VAL_45]] : i64 +!CHECK: %[[VAL_47:.*]] = arith.addi %[[VAL_46]], %[[VAL_45]] overflow : i64 !CHECK: fir.result %[[VAL_44]], %[[VAL_47]] : index, i64 !CHECK: } !CHECK: fir.store %[[VAL_48:.*]]#1 to %[[VAL_17]]#1 : !fir.ref diff --git a/flang/test/Lower/allocatable-polymorphic.f90 b/flang/test/Lower/allocatable-polymorphic.f90 index 852ce5159c18c..4d70e1ea4c739 100644 --- a/flang/test/Lower/allocatable-polymorphic.f90 +++ b/flang/test/Lower/allocatable-polymorphic.f90 @@ -267,7 +267,7 @@ subroutine test_allocatable() ! CHECK: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[P_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none ! CHECK: %[[P_CAST:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[P_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[P_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> ! CHECK: %[[C1_CAST:.*]] = fir.convert %[[C1_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> @@ -276,7 +276,7 @@ subroutine test_allocatable() ! CHECK: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[C1_CAST]], %[[TYPE_DESC_P1_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none ! CHECK: %[[C1_CAST:.*]] = fir.convert %[[C1_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C1_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C1_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{p1:!fir.type<_QMpolyTp1{a:i32,b:i32}>,c:i32}> ! CHECK: %[[C2_CAST:.*]] = fir.convert %[[C2_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> @@ -285,7 +285,7 @@ subroutine test_allocatable() ! CHECK: %[[C0:.*]] = arith.constant 0 : i32 ! CHECK: fir.call @_FortranAAllocatableInitDerivedForAllocate(%[[C2_CAST]], %[[TYPE_DESC_P2_CAST]], %[[RANK]], %[[C0]]) {{.*}}: (!fir.ref>, !fir.ref, i32, i32) -> none ! CHECK: %[[C2_CAST:.*]] = fir.convert %[[C2_DECL]]#1 : (!fir.ref>>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C2_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C2_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_P1:.*]] = fir.type_desc !fir.type<_QMpolyTp1{a:i32,b:i32}> ! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> @@ -300,7 +300,7 @@ subroutine test_allocatable() ! CHECK: %[[C10_I64:.*]] = fir.convert %[[C10]] : (i32) -> i64 ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableSetBounds(%[[C3_CAST]], %[[C0]], %[[C1_I64]], %[[C10_I64]]) {{.*}}: (!fir.ref>, i32, i64, i64) -> none ! CHECK: %[[C3_CAST:.*]] = fir.convert %[[C3_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C3_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C3_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[TYPE_DESC_P2:.*]] = fir.type_desc !fir.type<_QMpolyTp2{p1:!fir.type<_QMpolyTp1{a:i32,b:i32}>,c:i32}> ! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> @@ -316,7 +316,7 @@ subroutine test_allocatable() ! CHECK: %[[C20_I64:.*]] = fir.convert %[[C20]] : (i32) -> i64 ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableSetBounds(%[[C4_CAST]], %[[C0]], %[[C1_I64]], %[[C20_I64]]) {{.*}}: (!fir.ref>, i32, i64, i64) -> none ! CHECK: %[[C4_CAST:.*]] = fir.convert %[[C4_DECL]]#1 : (!fir.ref>>>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C4_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[C4_CAST]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[C1_LOAD1:.*]] = fir.load %[[C1_DECL]]#0 : !fir.ref>>> ! CHECK: fir.dispatch "proc1"(%[[C1_LOAD1]] : !fir.class>>) @@ -390,7 +390,7 @@ subroutine test_unlimited_polymorphic_with_intrinsic_type_spec() ! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableInitIntrinsicForAllocate(%[[BOX_NONE]], %[[CAT]], %[[KIND]], %[[RANK]], %[[CORANK]]) {{.*}} : (!fir.ref>, i32, i32, i32, i32) -> none ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[P_DECL]]#1 : (!fir.ref>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[PTR_DECL]]#1 : (!fir.ref>>) -> !fir.ref> ! CHECK: %[[CAT:.*]] = arith.constant 1 : i32 @@ -573,7 +573,7 @@ subroutine test_allocatable_up_character() ! CHECK: %[[CORANK:.*]] = arith.constant 0 : i32 ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableInitCharacterForAllocate(%[[A_NONE]], %[[LEN]], %[[KIND]], %[[RANK]], %[[CORANK]]) {{.*}} : (!fir.ref>, i64, i32, i32, i32) -> none ! CHECK: %[[A_NONE:.*]] = fir.convert %[[A_DECL]]#1 : (!fir.ref>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[A_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[A_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 end module @@ -592,17 +592,17 @@ program test_alloc ! LLVM-LABEL: define void @_QMpolyPtest_allocatable() ! LLVM: %{{.*}} = call {} @_FortranAAllocatableInitDerivedForAllocate(ptr %{{.*}}, ptr @_QMpolyEXdtXp1, i32 0, i32 0) -! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr %{{.*}}, i64 -1, i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) +! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr %{{.*}}, i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) ! LLVM: %{{.*}} = call {} @_FortranAAllocatableInitDerivedForAllocate(ptr %{{.*}}, ptr @_QMpolyEXdtXp1, i32 0, i32 0) -! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr %{{.*}}, i64 -1, i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) +! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr %{{.*}}, i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) ! LLVM: %{{.*}} = call {} @_FortranAAllocatableInitDerivedForAllocate(ptr %{{.*}}, ptr @_QMpolyEXdtXp2, i32 0, i32 0) -! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr %{{.*}}, i64 -1, i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) +! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr %{{.*}}, i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) ! LLVM: %{{.*}} = call {} @_FortranAAllocatableInitDerivedForAllocate(ptr %{{.*}}, ptr @_QMpolyEXdtXp1, i32 1, i32 0) ! LLVM: %{{.*}} = call {} @_FortranAAllocatableSetBounds(ptr %{{.*}}, i32 0, i64 1, i64 10) -! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr %{{.*}}, i64 -1, i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) +! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr %{{.*}}, i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) ! LLVM: %{{.*}} = call {} @_FortranAAllocatableInitDerivedForAllocate(ptr %{{.*}}, ptr @_QMpolyEXdtXp2, i32 1, i32 0) ! LLVM: %{{.*}} = call {} @_FortranAAllocatableSetBounds(ptr %{{.*}}, i32 0, i64 1, i64 20) -! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr %{{.*}}, i64 -1, i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) +! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr %{{.*}}, i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) ! LLVM-COUNT-2: call void %{{[0-9]*}}() ! LLVM: call void @llvm.memcpy.p0.p0.i32 @@ -683,5 +683,5 @@ program test_alloc ! LLVM: store { ptr, i64, i32, i8, i8, i8, i8, ptr, [1 x i64] } { ptr null, i64 ptrtoint (ptr getelementptr (%_QMpolyTp1, ptr null, i32 1) to i64), i32 20240719, i8 0, i8 42, i8 2, i8 1, ptr @_QMpolyEXdtXp1, [1 x i64] zeroinitializer }, ptr %[[ALLOCA1:[0-9]*]] ! LLVM: call void @llvm.memcpy.p0.p0.i32(ptr %[[ALLOCA2:[0-9]+]], ptr %[[ALLOCA1]], i32 40, i1 false) ! LLVM: %{{.*}} = call {} @_FortranAAllocatableInitDerivedForAllocate(ptr %[[ALLOCA2]], ptr @_QMpolyEXdtXp1, i32 0, i32 0) -! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr %[[ALLOCA2]], i64 -1, i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) +! LLVM: %{{.*}} = call i32 @_FortranAAllocatableAllocate(ptr %[[ALLOCA2]], i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) ! LLVM: %{{.*}} = call i32 @_FortranAAllocatableDeallocatePolymorphic(ptr %[[ALLOCA2]], ptr {{.*}}, i1 false, ptr null, ptr @_QQclX{{.*}}, i32 {{.*}}) diff --git a/flang/test/Lower/allocatable-runtime.f90 b/flang/test/Lower/allocatable-runtime.f90 index effd0a3a93b84..3f1f8a86b7d07 100644 --- a/flang/test/Lower/allocatable-runtime.f90 +++ b/flang/test/Lower/allocatable-runtime.f90 @@ -31,7 +31,7 @@ subroutine foo() ! CHECK: fir.call @{{.*}}AllocatableSetBounds(%[[xBoxCast2]], %c0{{.*}}, %[[xlbCast]], %[[xubCast]]) {{.*}}: (!fir.ref>, i32, i64, i64) -> none ! CHECK-DAG: %[[xBoxCast3:.*]] = fir.convert %[[xBoxAddr]] : (!fir.ref>>>) -> !fir.ref> ! CHECK-DAG: %[[sourceFile:.*]] = fir.convert %{{.*}} -> !fir.ref - ! CHECK: fir.call @{{.*}}AllocatableAllocate(%[[xBoxCast3]], %c-1{{.*}}, %false{{.*}}, %[[errMsg]], %[[sourceFile]], %{{.*}}) {{.*}}: (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 + ! CHECK: fir.call @{{.*}}AllocatableAllocate(%[[xBoxCast3]], %false{{.*}}, %[[errMsg]], %[[sourceFile]], %{{.*}}) {{.*}}: (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! Simply check that we are emitting the right numebr of set bound for y and z. Otherwise, this is just like x. ! CHECK: fir.convert %[[yBoxAddr]] : (!fir.ref>>>) -> !fir.ref> @@ -180,4 +180,4 @@ subroutine mold_allocation() ! CHECK: %[[M_BOX_NONE:.*]] = fir.convert %[[EMBOX_M]] : (!fir.box>) -> !fir.box ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableApplyMold(%[[A_BOX_NONE]], %[[M_BOX_NONE]], %[[RANK]]) {{.*}} : (!fir.ref>, !fir.box, i32) -> none ! CHECK: %[[A_BOX_NONE:.*]] = fir.convert %[[A]] : (!fir.ref>>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[A_BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[A_BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 diff --git a/flang/test/Lower/allocate-mold.f90 b/flang/test/Lower/allocate-mold.f90 index 831b26022dd46..0cc10fc9016de 100644 --- a/flang/test/Lower/allocate-mold.f90 +++ b/flang/test/Lower/allocate-mold.f90 @@ -16,7 +16,7 @@ subroutine scalar_mold_allocation() ! CHECK: %[[A_REF_BOX_NONE1:.*]] = fir.convert %[[A]] : (!fir.ref>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableApplyMold(%[[A_REF_BOX_NONE1]], %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, !fir.box, i32) -> none ! CHECK: %[[A_REF_BOX_NONE2:.*]] = fir.convert %[[A]] : (!fir.ref>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[A_REF_BOX_NONE2]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[A_REF_BOX_NONE2]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 subroutine array_scalar_mold_allocation() real, allocatable :: a(:) @@ -40,4 +40,4 @@ end subroutine array_scalar_mold_allocation ! CHECK: %[[REF_BOX_A1:.*]] = fir.convert %1 : (!fir.ref>>>) -> !fir.ref> ! CHECK: %{{.*}} = fir.call @_FortranAAllocatableSetBounds(%[[REF_BOX_A1]], {{.*}},{{.*}}, {{.*}}) fastmath : (!fir.ref>, i32, i64, i64) -> none ! CHECK: %[[REF_BOX_A2:.*]] = fir.convert %[[A]] : (!fir.ref>>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[REF_BOX_A2]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[REF_BOX_A2]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 diff --git a/flang/test/Lower/array-character.f90 b/flang/test/Lower/array-character.f90 index c93ef4be30823..53adc5c02958c 100644 --- a/flang/test/Lower/array-character.f90 +++ b/flang/test/Lower/array-character.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -hlfir=false %s -o - | fir-opt --canonicalize --cse | FileCheck %s +! RUN: bbc -hlfir=false -fwrapv %s -o - | fir-opt --canonicalize --cse | FileCheck %s ! CHECK-LABEL: func @_QPissue( ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}, %[[VAL_1:.*]]: !fir.boxchar<1>{{.*}}) { diff --git a/flang/test/Lower/array-derived-assignments.f90 b/flang/test/Lower/array-derived-assignments.f90 index 71e61f651302a..f4e51271d5936 100644 --- a/flang/test/Lower/array-derived-assignments.f90 +++ b/flang/test/Lower/array-derived-assignments.f90 @@ -1,5 +1,5 @@ ! Test derived type assignment lowering inside array expression -! RUN: bbc -hlfir=false %s -o - | FileCheck %s +! RUN: bbc -hlfir=false -fwrapv %s -o - | FileCheck %s module array_derived_assign type simple_copy diff --git a/flang/test/Lower/array-derived.f90 b/flang/test/Lower/array-derived.f90 index b5eb7621c90f1..a0c55f5d88255 100644 --- a/flang/test/Lower/array-derived.f90 +++ b/flang/test/Lower/array-derived.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -hlfir=false %s -o - | FileCheck %s +! RUN: bbc -hlfir=false -fwrapv %s -o - | FileCheck %s module cs type r diff --git a/flang/test/Lower/array-elemental-calls-char-byval.f90 b/flang/test/Lower/array-elemental-calls-char-byval.f90 index c321614e7fc5b..682191fc78956 100644 --- a/flang/test/Lower/array-elemental-calls-char-byval.f90 +++ b/flang/test/Lower/array-elemental-calls-char-byval.f90 @@ -1,6 +1,6 @@ ! Test lowering of elemental calls with character argument ! with the VALUE attribute. -! RUN: bbc -hlfir=false -o - %s | FileCheck %s +! RUN: bbc -hlfir=false -fwrapv -o - %s | FileCheck %s module char_elem_byval diff --git a/flang/test/Lower/array-elemental-calls-char.f90 b/flang/test/Lower/array-elemental-calls-char.f90 index 603cc677805fc..00e2f8e8f9c12 100644 --- a/flang/test/Lower/array-elemental-calls-char.f90 +++ b/flang/test/Lower/array-elemental-calls-char.f90 @@ -1,6 +1,6 @@ ! Test lowering of elemental calls with character argument ! without the VALUE attribute. -! RUN: bbc -hlfir=false -o - %s | FileCheck %s +! RUN: bbc -hlfir=false -fwrapv -o - %s | FileCheck %s module char_elem diff --git a/flang/test/Lower/array-expression-assumed-size.f90 b/flang/test/Lower/array-expression-assumed-size.f90 index ae35da951538b..2fbf315aff114 100644 --- a/flang/test/Lower/array-expression-assumed-size.f90 +++ b/flang/test/Lower/array-expression-assumed-size.f90 @@ -1,5 +1,5 @@ ! RUN: bbc --emit-fir -hlfir=false %s -o - | FileCheck %s -! RUN: bbc -hlfir=false %s -o - | FileCheck --check-prefix=PostOpt %s +! RUN: bbc -hlfir=false -fwrapv %s -o - | FileCheck --check-prefix=PostOpt %s subroutine assumed_size_test(a) diff --git a/flang/test/Lower/array-expression-slice-1.f90 b/flang/test/Lower/array-expression-slice-1.f90 index 1524509024329..b597814bc0d9f 100644 --- a/flang/test/Lower/array-expression-slice-1.f90 +++ b/flang/test/Lower/array-expression-slice-1.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -hlfir=false -o - --outline-intrinsics %s | FileCheck %s +! RUN: bbc -hlfir=false -fwrapv -o - --outline-intrinsics %s | FileCheck %s ! CHECK-LABEL: func @_QQmain() attributes {fir.bindc_name = "p"} { ! CHECK-DAG: %[[VAL_0:.*]] = arith.constant 10 : index diff --git a/flang/test/Lower/array-substring.f90 b/flang/test/Lower/array-substring.f90 index 2e283997e3e00..02101039120e9 100644 --- a/flang/test/Lower/array-substring.f90 +++ b/flang/test/Lower/array-substring.f90 @@ -1,5 +1,7 @@ ! RUN: bbc -hlfir=false %s -o - | FileCheck %s -! RUN: bbc -hlfir=false -integer-overflow %s -o - | FileCheck %s --check-prefix=NSW +! RUN: bbc -hlfir=false -fwrapv %s -o - | FileCheck %s --check-prefix=NO-NSW + +! NO-NSW-NOT: overflow ! CHECK-LABEL: func @_QPtest( ! CHECK-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}) -> !fir.array<1x!fir.logical<4>> { @@ -32,8 +34,9 @@ ! CHECK: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (i1) -> !fir.logical<4> ! CHECK: %[[VAL_27:.*]] = fir.array_coor %[[VAL_8]](%[[VAL_9]]) %[[VAL_15]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref> ! CHECK: fir.store %[[VAL_26]] to %[[VAL_27]] : !fir.ref> +! CHECK: %[[VAL_15_NSW:.*]] = arith.addi %[[VAL_12]], %[[VAL_1]] overflow : index ! CHECK: %[[VAL_28:.*]] = arith.subi %[[VAL_13]], %[[VAL_1]] : index -! CHECK: br ^bb1(%[[VAL_15]], %[[VAL_28]] : index, index) +! CHECK: br ^bb1(%[[VAL_15_NSW]], %[[VAL_28]] : index, index) ! CHECK: ^bb3: ! CHECK: %[[VAL_29:.*]] = fir.load %[[VAL_8]] : !fir.ref>> ! CHECK: return %[[VAL_29]] : !fir.array<1x!fir.logical<4>> @@ -46,42 +49,3 @@ function test(C) test = C(1:1)(1:8) == (/'ABCDabcd'/) end function test - -! NSW-LABEL: func @_QPtest( -! NSW-SAME: %[[VAL_0:.*]]: !fir.boxchar<1>{{.*}}) -> !fir.array<1x!fir.logical<4>> { -! NSW-DAG: %[[VAL_1:.*]] = arith.constant 1 : index -! NSW-DAG: %[[VAL_2:.*]] = arith.constant 0 : index -! NSW-DAG: %[[VAL_3:.*]] = arith.constant 0 : i32 -! NSW-DAG: %[[VAL_4:.*]] = arith.constant 8 : index -! NSW: %[[VAL_6:.*]]:2 = fir.unboxchar %[[VAL_0]] : (!fir.boxchar<1>) -> (!fir.ref>, index) -! NSW: %[[VAL_7:.*]] = fir.convert %[[VAL_6]]#0 : (!fir.ref>) -> !fir.ref>> -! NSW: %[[VAL_8:.*]] = fir.alloca !fir.array<1x!fir.logical<4>> {bindc_name = "test", uniq_name = "_QFtestEtest"} -! NSW: %[[VAL_9:.*]] = fir.shape %[[VAL_1]] : (index) -> !fir.shape<1> -! NSW: %[[VAL_10:.*]] = fir.slice %[[VAL_1]], %[[VAL_1]], %[[VAL_1]] : (index, index, index) -> !fir.slice<1> -! NSW: %[[VAL_11:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref>> -! NSW: br ^bb1(%[[VAL_2]], %[[VAL_1]] : index, index) -! NSW: ^bb1(%[[VAL_12:.*]]: index, %[[VAL_13:.*]]: index): -! NSW: %[[VAL_14:.*]] = arith.cmpi sgt, %[[VAL_13]], %[[VAL_2]] : index -! NSW: cond_br %[[VAL_14]], ^bb2, ^bb3 -! NSW: ^bb2: -! NSW: %[[VAL_15:.*]] = arith.addi %[[VAL_12]], %[[VAL_1]] : index -! NSW: %[[VAL_16:.*]] = fir.array_coor %[[VAL_7]](%[[VAL_9]]) {{\[}}%[[VAL_10]]] %[[VAL_15]] : (!fir.ref>>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.ref> -! NSW: %[[VAL_17:.*]] = fir.convert %[[VAL_16]] : (!fir.ref>) -> !fir.ref>> -! NSW: %[[VAL_18:.*]] = fir.coordinate_of %[[VAL_17]], %[[VAL_2]] : (!fir.ref>>, index) -> !fir.ref> -! NSW: %[[VAL_19:.*]] = fir.convert %[[VAL_18]] : (!fir.ref>) -> !fir.ref> -! NSW: %[[VAL_20:.*]] = fir.array_coor %[[VAL_11]](%[[VAL_9]]) %[[VAL_15]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref> -! NSW: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.ref>) -> !fir.ref -! NSW: %[[VAL_22:.*]] = fir.convert %[[VAL_20]] : (!fir.ref>) -> !fir.ref -! NSW: %[[VAL_23:.*]] = fir.convert %[[VAL_4]] : (index) -> i64 -! NSW: %[[VAL_24:.*]] = fir.call @_FortranACharacterCompareScalar1(%[[VAL_21]], %[[VAL_22]], %[[VAL_23]], %[[VAL_23]]) {{.*}}: (!fir.ref, !fir.ref, i64, i64) -> i32 -! NSW: %[[VAL_25:.*]] = arith.cmpi eq, %[[VAL_24]], %[[VAL_3]] : i32 -! NSW: %[[VAL_26:.*]] = fir.convert %[[VAL_25]] : (i1) -> !fir.logical<4> -! NSW: %[[VAL_27:.*]] = fir.array_coor %[[VAL_8]](%[[VAL_9]]) %[[VAL_15]] : (!fir.ref>>, !fir.shape<1>, index) -> !fir.ref> -! NSW: fir.store %[[VAL_26]] to %[[VAL_27]] : !fir.ref> -! NSW: %[[VAL_15_NSW:.*]] = arith.addi %[[VAL_12]], %[[VAL_1]] overflow : index -! NSW: %[[VAL_28:.*]] = arith.subi %[[VAL_13]], %[[VAL_1]] : index -! NSW: br ^bb1(%[[VAL_15_NSW]], %[[VAL_28]] : index, index) -! NSW: ^bb3: -! NSW: %[[VAL_29:.*]] = fir.load %[[VAL_8]] : !fir.ref>> -! NSW: return %[[VAL_29]] : !fir.array<1x!fir.logical<4>> -! NSW: } diff --git a/flang/test/Lower/array-temp.f90 b/flang/test/Lower/array-temp.f90 index 10c5ee91d44bd..718aef84a4e85 100644 --- a/flang/test/Lower/array-temp.f90 +++ b/flang/test/Lower/array-temp.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -hlfir=false %s -o - | FileCheck %s +! RUN: bbc -hlfir=false -fwrapv %s -o - | FileCheck %s ! CHECK-LABEL: func @_QPss1() subroutine ss1 diff --git a/flang/test/Lower/components.f90 b/flang/test/Lower/components.f90 index e1582a8a31e0d..28e836c5d1045 100644 --- a/flang/test/Lower/components.f90 +++ b/flang/test/Lower/components.f90 @@ -1,4 +1,4 @@ -! RUN: bbc -hlfir=false %s -o - | FileCheck %s +! RUN: bbc -hlfir=false -fwrapv %s -o - | FileCheck %s module components_test type t1 diff --git a/flang/test/Lower/do_concurrent_local_default_init.f90 b/flang/test/Lower/do_concurrent_local_default_init.f90 new file mode 100644 index 0000000000000..1766e0a104ff6 --- /dev/null +++ b/flang/test/Lower/do_concurrent_local_default_init.f90 @@ -0,0 +1,52 @@ +! Test default initialization of DO CONCURRENT LOCAL() entities. +! RUN: bbc -emit-hlfir -I nowhere -o - %s | FileCheck %s + +subroutine test_ptr(p) + interface + pure subroutine takes_ptr(p) + character(*), intent(in), pointer :: p(:) + end subroutine + end interface + character(*), pointer :: p(:) + integer :: i + do concurrent (i=1:10) local(p) + call takes_ptr(p) + end do +end subroutine + +subroutine test_default_init() + type t + integer :: i = 2 + end type + integer :: i, res(4) + type(t) :: a + do concurrent (i=1:4) local(a) + res(i) = a%i + end do + call something(res) +end subroutine +! CHECK-LABEL: func.func @_QPtest_ptr( +! CHECK-SAME: %[[VAL_0:.*]]: !fir.ref>>>> {fir.bindc_name = "p"}) { +! CHECK: %[[VAL_6:.*]] = fir.load %[[VAL_0]] : !fir.ref>>>> +! CHECK: %[[VAL_7:.*]] = fir.box_elesize %[[VAL_6]] : (!fir.box>>>) -> index +! CHECK: fir.do_loop +! CHECK: %[[VAL_16:.*]] = fir.alloca !fir.box>>> {bindc_name = "p", pinned, uniq_name = "_QFtest_ptrEp"} +! CHECK: %[[VAL_17:.*]] = fir.zero_bits !fir.ptr>> +! CHECK: %[[VAL_18:.*]] = arith.constant 0 : index +! CHECK: %[[VAL_19:.*]] = fir.shape %[[VAL_18]] : (index) -> !fir.shape<1> +! CHECK: %[[VAL_20:.*]] = fir.embox %[[VAL_17]](%[[VAL_19]]) typeparams %[[VAL_7]] : (!fir.ptr>>, !fir.shape<1>, index) -> !fir.box>>> +! CHECK: fir.store %[[VAL_20]] to %[[VAL_16]] : !fir.ref>>>> +! CHECK: %[[VAL_21:.*]]:2 = hlfir.declare %[[VAL_16]] {fortran_attrs = #fir.var_attrs, uniq_name = "_QFtest_ptrEp"} : (!fir.ref>>>>) -> (!fir.ref>>>>, !fir.ref>>>>) +! CHECK: fir.call @_QPtakes_ptr(%[[VAL_21]]#0) proc_attrs fastmath : (!fir.ref>>>>) -> () +! CHECK: } +! CHECK: return +! CHECK: } + +! CHECK-LABEL: func.func @_QPtest_default_init( +! CHECK: fir.do_loop +! CHECK: %[[VAL_26:.*]] = fir.alloca !fir.type<_QFtest_default_initTt{i:i32}> {bindc_name = "a", pinned, uniq_name = "_QFtest_default_initEa"} +! CHECK: %[[VAL_27:.*]] = fir.embox %[[VAL_26]] : (!fir.ref>) -> !fir.box> +! CHECK: %[[VAL_30:.*]] = fir.convert %[[VAL_27]] : (!fir.box>) -> !fir.box +! CHECK: %[[VAL_32:.*]] = fir.call @_FortranAInitialize(%[[VAL_30]], {{.*}} +! CHECK: %[[VAL_33:.*]]:2 = hlfir.declare %[[VAL_26]] {uniq_name = "_QFtest_default_initEa"} : (!fir.ref>) -> (!fir.ref>, !fir.ref>) +! CHECK: } diff --git a/flang/test/Lower/do_loop.f90 b/flang/test/Lower/do_loop.f90 index a46e6c947391b..5d8343b8d68a4 100644 --- a/flang/test/Lower/do_loop.f90 +++ b/flang/test/Lower/do_loop.f90 @@ -1,17 +1,17 @@ ! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false -o - %s | FileCheck %s ! RUN: %flang_fc1 -mllvm --use-desc-for-alloc=false -emit-fir -flang-deprecated-no-hlfir -o - %s | FileCheck %s -! RUN: %flang_fc1 -mllvm --use-desc-for-alloc=false -emit-fir -flang-deprecated-no-hlfir -flang-experimental-integer-overflow -o - %s | FileCheck %s --check-prefix=NSW +! RUN: %flang_fc1 -mllvm --use-desc-for-alloc=false -emit-fir -flang-deprecated-no-hlfir -fwrapv -o - %s | FileCheck %s --check-prefix=NO-NSW ! Simple tests for structured ordered loops with loop-control. ! Tests the structure of the loop, storage to index variable and return and ! storage of the final value of the index variable. +! NO-NSW-NOT: overflow + ! Test a simple loop with the final value of the index variable read outside the loop ! CHECK-LABEL: simple_loop -! NSW-LABEL: simple_loop subroutine simple_loop ! CHECK: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_loopEi"} - ! NSW: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_loopEi"} integer :: i ! CHECK: %[[C1:.*]] = arith.constant 1 : i32 @@ -21,18 +21,14 @@ subroutine simple_loop ! CHECK: %[[C1:.*]] = arith.constant 1 : index ! CHECK: %[[LB:.*]] = fir.convert %[[C1_CVT]] : (index) -> i32 ! CHECK: %[[LI_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] = - ! NSW: %[[LI_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] = ! CHECK-SAME: %[[C1_CVT]] to %[[C5_CVT]] step %[[C1]] ! CHECK-SAME: iter_args(%[[IV:.*]] = %[[LB]]) -> (index, i32) { do i=1,5 ! CHECK: fir.store %[[IV]] to %[[I_REF]] : !fir.ref - ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[C1]] : index - ! NSW: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[C1:.*]] overflow : index + ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[C1]] overflow : index ! CHECK: %[[STEPCAST:.*]] = fir.convert %[[C1]] : (index) -> i32 ! CHECK: %[[IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref - ! NSW: %[[IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref - ! CHECK: %[[IVINC:.*]] = arith.addi %[[IVLOAD]], %[[STEPCAST]] : i32 - ! NSW: %[[IVINC:.*]] = arith.addi %[[IVLOAD]], %[[STEPCAST:.*]] overflow : i32 + ! CHECK: %[[IVINC:.*]] = arith.addi %[[IVLOAD]], %[[STEPCAST]] overflow : i32 ! CHECK: fir.result %[[LI_NEXT]], %[[IVINC]] : index, i32 ! CHECK: } end do @@ -44,14 +40,11 @@ subroutine simple_loop ! Test a 2-nested loop with a body composed of a reduction. Values are read from a 2d array. ! CHECK-LABEL: nested_loop -! NSW-LABEL: nested_loop subroutine nested_loop ! CHECK: %[[ARR_REF:.*]] = fir.alloca !fir.array<5x5xi32> {bindc_name = "arr", uniq_name = "_QFnested_loopEarr"} ! CHECK: %[[ASUM_REF:.*]] = fir.alloca i32 {bindc_name = "asum", uniq_name = "_QFnested_loopEasum"} ! CHECK: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFnested_loopEi"} - ! NSW: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFnested_loopEi"} ! CHECK: %[[J_REF:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFnested_loopEj"} - ! NSW: %[[J_REF:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFnested_loopEj"} integer :: asum, arr(5,5) integer :: i, j asum = 0 @@ -62,7 +55,6 @@ subroutine nested_loop ! CHECK: %[[ST_I:.*]] = arith.constant 1 : index ! CHECK: %[[I_LB:.*]] = fir.convert %[[S_I_CVT]] : (index) -> i32 ! CHECK: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] = - ! NSW: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] = ! CHECK-SAME: %[[S_I_CVT]] to %[[E_I_CVT]] step %[[ST_I]] ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (index, i32) { do i=1,5 @@ -74,7 +66,6 @@ subroutine nested_loop ! CHECK: %[[ST_J:.*]] = arith.constant 1 : index ! CHECK: %[[J_LB:.*]] = fir.convert %[[S_J_CVT]] : (index) -> i32 ! CHECK: %[[J_RES:.*]]:2 = fir.do_loop %[[LJ:[^ ]*]] = - ! NSW: %[[J_RES:.*]]:2 = fir.do_loop %[[LJ:[^ ]*]] = ! CHECK-SAME: %[[S_J_CVT]] to %[[E_J_CVT]] step %[[ST_J]] ! CHECK-SAME: iter_args(%[[J_IV:.*]] = %[[J_LB]]) -> (index, i32) { do j=1,5 @@ -93,24 +84,18 @@ subroutine nested_loop ! CHECK: %[[ASUM_NEW:.*]] = arith.addi %[[ASUM]], %[[ARR_VAL]] : i32 ! CHECK: fir.store %[[ASUM_NEW]] to %[[ASUM_REF]] : !fir.ref asum = asum + arr(i,j) - ! CHECK: %[[LJ_NEXT:.*]] = arith.addi %[[LJ]], %[[ST_J]] : index - ! NSW: %[[LJ_NEXT:.*]] = arith.addi %[[LJ]], %[[ST_J:.*]] overflow : index + ! CHECK: %[[LJ_NEXT:.*]] = arith.addi %[[LJ]], %[[ST_J]] overflow : index ! CHECK: %[[J_STEPCAST:.*]] = fir.convert %[[ST_J]] : (index) -> i32 ! CHECK: %[[J_IVLOAD:.*]] = fir.load %[[J_REF]] : !fir.ref - ! NSW: %[[J_IVLOAD:.*]] = fir.load %[[J_REF]] : !fir.ref - ! CHECK: %[[J_IVINC:.*]] = arith.addi %[[J_IVLOAD]], %[[J_STEPCAST]] : i32 - ! NSW: %[[J_IVINC:.*]] = arith.addi %[[J_IVLOAD]], %[[J_STEPCAST:.*]] overflow : i32 + ! CHECK: %[[J_IVINC:.*]] = arith.addi %[[J_IVLOAD]], %[[J_STEPCAST]] overflow : i32 ! CHECK: fir.result %[[LJ_NEXT]], %[[J_IVINC]] : index, i32 ! CHECK: } end do ! CHECK: fir.store %[[J_RES]]#1 to %[[J_REF]] : !fir.ref - ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_I]] : index - ! NSW: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_I:.*]] overflow : index + ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_I]] overflow : index ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[ST_I]] : (index) -> i32 ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref - ! NSW: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref - ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] : i32 - ! NSW: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST:.*]] overflow : i32 + ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow : i32 ! CHECK: fir.result %[[LI_NEXT]], %[[I_IVINC]] : index, i32 ! CHECK: } end do @@ -119,11 +104,9 @@ subroutine nested_loop ! Test a downcounting loop ! CHECK-LABEL: down_counting_loop -! NSW-LABEL: down_counting_loop subroutine down_counting_loop() integer :: i ! CHECK: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFdown_counting_loopEi"} - ! NSW: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFdown_counting_loopEi"} ! CHECK: %[[C5:.*]] = arith.constant 5 : i32 ! CHECK: %[[C5_CVT:.*]] = fir.convert %[[C5]] : (i32) -> index @@ -133,18 +116,14 @@ subroutine down_counting_loop() ! CHECK: %[[CMINUS1_STEP_CVT:.*]] = fir.convert %[[CMINUS1]] : (i32) -> index ! CHECK: %[[I_LB:.*]] = fir.convert %[[C5_CVT]] : (index) -> i32 ! CHECK: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] = - ! NSW: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] = ! CHECK-SAME: %[[C5_CVT]] to %[[C1_CVT]] step %[[CMINUS1_STEP_CVT]] ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (index, i32) { do i=5,1,-1 ! CHECK: fir.store %[[I_IV]] to %[[I_REF]] : !fir.ref - ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[CMINUS1_STEP_CVT]] : index - ! NSW: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[CMINUS1_STEP_CVT:.*]] overflow : index + ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[CMINUS1_STEP_CVT]] overflow : index ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[CMINUS1_STEP_CVT]] : (index) -> i32 ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref - ! NSW: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref - ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] : i32 - ! NSW: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST:.*]] overflow : i32 + ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow : i32 ! CHECK: fir.result %[[LI_NEXT]], %[[I_IVINC]] : index, i32 ! CHECK: } end do @@ -153,7 +132,6 @@ subroutine down_counting_loop() ! Test a general loop with a variable step ! CHECK-LABEL: loop_with_variable_step -! NSW-LABEL: loop_with_variable_step ! CHECK-SAME: (%[[S_REF:.*]]: !fir.ref {fir.bindc_name = "s"}, %[[E_REF:.*]]: !fir.ref {fir.bindc_name = "e"}, %[[ST_REF:.*]]: !fir.ref {fir.bindc_name = "st"}) { subroutine loop_with_variable_step(s,e,st) integer :: s, e, st @@ -166,18 +144,14 @@ subroutine loop_with_variable_step(s,e,st) ! CHECK: %[[ST_CVT:.*]] = fir.convert %[[ST]] : (i32) -> index ! CHECK: %[[I_LB:.*]] = fir.convert %[[S_CVT]] : (index) -> i32 ! CHECK: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] = - ! NSW: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] = ! CHECK-SAME: %[[S_CVT]] to %[[E_CVT]] step %[[ST_CVT]] ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (index, i32) { do i=s,e,st ! CHECK: fir.store %[[I_IV]] to %[[I_REF]] : !fir.ref - ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_CVT]] : index - ! NSW: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_CVT:.*]] overflow : index + ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_CVT]] overflow : index ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[ST_CVT]] : (index) -> i32 ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref - ! NSW: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref - ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] : i32 - ! NSW: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST:.*]] overflow : i32 + ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow : i32 ! CHECK: fir.result %[[LI_NEXT]], %[[I_IVINC]] : index, i32 ! CHECK: } end do @@ -186,13 +160,11 @@ subroutine loop_with_variable_step(s,e,st) ! Test usage of pointer variables as index, start, end and step variables ! CHECK-LABEL: loop_with_pointer_variables -! NSW-LABEL: loop_with_pointer_variables ! CHECK-SAME: (%[[S_REF:.*]]: !fir.ref {fir.bindc_name = "s", fir.target}, %[[E_REF:.*]]: !fir.ref {fir.bindc_name = "e", fir.target}, %[[ST_REF:.*]]: !fir.ref {fir.bindc_name = "st", fir.target}) { subroutine loop_with_pointer_variables(s,e,st) ! CHECK: %[[E_PTR_REF:.*]] = fir.alloca !fir.ptr {uniq_name = "_QFloop_with_pointer_variablesEeptr.addr"} ! CHECK: %[[I_REF:.*]] = fir.alloca i32 {bindc_name = "i", fir.target, uniq_name = "_QFloop_with_pointer_variablesEi"} ! CHECK: %[[I_PTR_REF:.*]] = fir.alloca !fir.ptr {uniq_name = "_QFloop_with_pointer_variablesEiptr.addr"} -! NSW: %[[I_PTR_REF:.*]] = fir.alloca !fir.ptr {uniq_name = "_QFloop_with_pointer_variablesEiptr.addr"} ! CHECK: %[[S_PTR_REF:.*]] = fir.alloca !fir.ptr {uniq_name = "_QFloop_with_pointer_variablesEsptr.addr"} ! CHECK: %[[ST_PTR_REF:.*]] = fir.alloca !fir.ptr {uniq_name = "_QFloop_with_pointer_variablesEstptr.addr"} integer, target :: i @@ -213,7 +185,6 @@ subroutine loop_with_pointer_variables(s,e,st) stptr => st ! CHECK: %[[I_PTR:.*]] = fir.load %[[I_PTR_REF]] : !fir.ref> -! NSW: %[[I_PTR:.*]] = fir.load %[[I_PTR_REF]] : !fir.ref> ! CHECK: %[[S_PTR:.*]] = fir.load %[[S_PTR_REF]] : !fir.ref> ! CHECK: %[[S:.*]] = fir.load %[[S_PTR]] : !fir.ptr ! CHECK: %[[S_CVT:.*]] = fir.convert %[[S]] : (i32) -> index @@ -225,18 +196,14 @@ subroutine loop_with_pointer_variables(s,e,st) ! CHECK: %[[ST_CVT:.*]] = fir.convert %[[ST]] : (i32) -> index ! CHECK: %[[I_LB:.*]] = fir.convert %[[S_CVT]] : (index) -> i32 ! CHECK: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] = -! NSW: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] = ! CHECK-SAME: %[[S_CVT]] to %[[E_CVT]] step %[[ST_CVT]] ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (index, i32) { do iptr=sptr,eptr,stptr ! CHECK: fir.store %[[I_IV]] to %[[I_PTR]] : !fir.ptr -! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_CVT]] : index -! NSW: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_CVT:.*]] overflow : index +! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_CVT]] overflow : index ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[ST_CVT]] : (index) -> i32 ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_PTR]] : !fir.ptr -! NSW: %[[I_IVLOAD:.*]] = fir.load %[[I_PTR]] : !fir.ptr -! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] : i32 -! NSW: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST:.*]] overflow : i32 +! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow : i32 ! CHECK: fir.result %[[LI_NEXT]], %[[I_IVINC]] : index, i32 end do ! CHECK: } @@ -245,11 +212,9 @@ subroutine loop_with_pointer_variables(s,e,st) ! Test usage of non-default integer kind for loop control and loop index variable ! CHECK-LABEL: loop_with_non_default_integer -! NSW-LABEL: loop_with_non_default_integer ! CHECK-SAME: (%[[S_REF:.*]]: !fir.ref {fir.bindc_name = "s"}, %[[E_REF:.*]]: !fir.ref {fir.bindc_name = "e"}, %[[ST_REF:.*]]: !fir.ref {fir.bindc_name = "st"}) { subroutine loop_with_non_default_integer(s,e,st) ! CHECK: %[[I_REF:.*]] = fir.alloca i64 {bindc_name = "i", uniq_name = "_QFloop_with_non_default_integerEi"} - ! NSW: %[[I_REF:.*]] = fir.alloca i64 {bindc_name = "i", uniq_name = "_QFloop_with_non_default_integerEi"} integer(kind=8):: i ! CHECK: %[[S:.*]] = fir.load %[[S_REF]] : !fir.ref ! CHECK: %[[S_CVT:.*]] = fir.convert %[[S]] : (i64) -> index @@ -261,18 +226,14 @@ subroutine loop_with_non_default_integer(s,e,st) ! CHECK: %[[I_LB:.*]] = fir.convert %[[S_CVT]] : (index) -> i64 ! CHECK: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] = - ! NSW: %[[I_RES:.*]]:2 = fir.do_loop %[[LI:[^ ]*]] = ! CHECK-SAME: %[[S_CVT]] to %[[E_CVT]] step %[[ST_CVT]] ! CHECK-SAME: iter_args(%[[I_IV:.*]] = %[[I_LB]]) -> (index, i64) { do i=s,e,st ! CHECK: fir.store %[[I_IV]] to %[[I_REF]] : !fir.ref - ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_CVT]] : index - ! NSW: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_CVT:.*]] overflow : index + ! CHECK: %[[LI_NEXT:.*]] = arith.addi %[[LI]], %[[ST_CVT]] overflow : index ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[ST_CVT]] : (index) -> i64 ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref - ! NSW: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref - ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] : i64 - ! NSW: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST:.*]] overflow : i64 + ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow : i64 ! CHECK: fir.result %[[LI_NEXT]], %[[I_IVINC]] : index, i64 end do ! CHECK: } diff --git a/flang/test/Lower/do_loop_unstructured.f90 b/flang/test/Lower/do_loop_unstructured.f90 index e1a669e09c9a8..d8890b2d0926e 100644 --- a/flang/test/Lower/do_loop_unstructured.f90 +++ b/flang/test/Lower/do_loop_unstructured.f90 @@ -1,9 +1,11 @@ ! RUN: bbc -emit-fir -hlfir=false -o - %s | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -o - %s | FileCheck %s -! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -flang-experimental-integer-overflow -o - %s | FileCheck %s --check-prefix=NSW +! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fwrapv -o - %s | FileCheck %s --check-prefix=NO-NSW ! Tests for unstructured loops. +! NO-NSW-NOT: overflow + ! Test a simple unstructured loop. Test for the existence of, ! -> The initialization of the trip-count and loop-variable ! -> The branch to the body or the exit inside the header @@ -39,42 +41,12 @@ subroutine simple_unstructured() ! CHECK: fir.store %[[TRIP_VAR_NEXT]] to %[[TRIP_VAR_REF]] : !fir.ref ! CHECK: %[[LOOP_VAR:.*]] = fir.load %[[LOOP_VAR_REF]] : !fir.ref ! CHECK: %[[STEP_ONE_2:.*]] = arith.constant 1 : i32 -! CHECK: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_ONE_2]] : i32 +! CHECK: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_ONE_2]] overflow : i32 ! CHECK: fir.store %[[LOOP_VAR_NEXT]] to %[[LOOP_VAR_REF]] : !fir.ref ! CHECK: cf.br ^[[HEADER]] ! CHECK: ^[[EXIT]]: ! CHECK: return -! NSW-LABEL: simple_unstructured -! NSW: %[[TRIP_VAR_REF:.*]] = fir.alloca i32 -! NSW: %[[LOOP_VAR_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_unstructuredEi"} -! NSW: %[[ONE:.*]] = arith.constant 1 : i32 -! NSW: %[[HUNDRED:.*]] = arith.constant 100 : i32 -! NSW: %[[STEP_ONE:.*]] = arith.constant 1 : i32 -! NSW: %[[TMP1:.*]] = arith.subi %[[HUNDRED]], %[[ONE]] : i32 -! NSW: %[[TMP2:.*]] = arith.addi %[[TMP1]], %[[STEP_ONE]] : i32 -! NSW: %[[TRIP_COUNT:.*]] = arith.divsi %[[TMP2]], %[[STEP_ONE]] : i32 -! NSW: fir.store %[[TRIP_COUNT]] to %[[TRIP_VAR_REF]] : !fir.ref -! NSW: fir.store %[[ONE]] to %[[LOOP_VAR_REF]] : !fir.ref -! NSW: cf.br ^[[HEADER:.*]] -! NSW: ^[[HEADER]]: -! NSW: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_REF]] : !fir.ref -! NSW: %[[ZERO:.*]] = arith.constant 0 : i32 -! NSW: %[[COND:.*]] = arith.cmpi sgt, %[[TRIP_VAR]], %[[ZERO]] : i32 -! NSW: cf.cond_br %[[COND]], ^[[BODY:.*]], ^[[EXIT:.*]] -! NSW: ^[[BODY]]: -! NSW: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_REF]] : !fir.ref -! NSW: %[[ONE_1:.*]] = arith.constant 1 : i32 -! NSW: %[[TRIP_VAR_NEXT:.*]] = arith.subi %[[TRIP_VAR]], %[[ONE_1]] : i32 -! NSW: fir.store %[[TRIP_VAR_NEXT]] to %[[TRIP_VAR_REF]] : !fir.ref -! NSW: %[[LOOP_VAR:.*]] = fir.load %[[LOOP_VAR_REF]] : !fir.ref -! NSW: %[[STEP_ONE_2:.*]] = arith.constant 1 : i32 -! NSW: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_ONE_2]] overflow : i32 -! NSW: fir.store %[[LOOP_VAR_NEXT]] to %[[LOOP_VAR_REF]] : !fir.ref -! NSW: cf.br ^[[HEADER]] -! NSW: ^[[EXIT]]: -! NSW: return - ! Test an unstructured loop with a step. Mostly similar to the previous one. ! Only difference is a non-unit step. subroutine simple_unstructured_with_step() @@ -108,42 +80,12 @@ subroutine simple_unstructured_with_step() ! CHECK: fir.store %[[TRIP_VAR_NEXT]] to %[[TRIP_VAR_REF]] : !fir.ref ! CHECK: %[[LOOP_VAR:.*]] = fir.load %[[LOOP_VAR_REF]] : !fir.ref ! CHECK: %[[STEP_2:.*]] = arith.constant 2 : i32 -! CHECK: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_2]] : i32 +! CHECK: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_2]] overflow : i32 ! CHECK: fir.store %[[LOOP_VAR_NEXT]] to %[[LOOP_VAR_REF]] : !fir.ref ! CHECK: cf.br ^[[HEADER]] ! CHECK: ^[[EXIT]]: ! CHECK: return -! NSW-LABEL: simple_unstructured_with_step -! NSW: %[[TRIP_VAR_REF:.*]] = fir.alloca i32 -! NSW: %[[LOOP_VAR_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFsimple_unstructured_with_stepEi"} -! NSW: %[[ONE:.*]] = arith.constant 1 : i32 -! NSW: %[[HUNDRED:.*]] = arith.constant 100 : i32 -! NSW: %[[STEP:.*]] = arith.constant 2 : i32 -! NSW: %[[TMP1:.*]] = arith.subi %[[HUNDRED]], %[[ONE]] : i32 -! NSW: %[[TMP2:.*]] = arith.addi %[[TMP1]], %[[STEP]] : i32 -! NSW: %[[TRIP_COUNT:.*]] = arith.divsi %[[TMP2]], %[[STEP]] : i32 -! NSW: fir.store %[[TRIP_COUNT]] to %[[TRIP_VAR_REF]] : !fir.ref -! NSW: fir.store %[[ONE]] to %[[LOOP_VAR_REF]] : !fir.ref -! NSW: cf.br ^[[HEADER:.*]] -! NSW: ^[[HEADER]]: -! NSW: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_REF]] : !fir.ref -! NSW: %[[ZERO:.*]] = arith.constant 0 : i32 -! NSW: %[[COND:.*]] = arith.cmpi sgt, %[[TRIP_VAR]], %[[ZERO]] : i32 -! NSW: cf.cond_br %[[COND]], ^[[BODY:.*]], ^[[EXIT:.*]] -! NSW: ^[[BODY]]: -! NSW: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_REF]] : !fir.ref -! NSW: %[[ONE_1:.*]] = arith.constant 1 : i32 -! NSW: %[[TRIP_VAR_NEXT:.*]] = arith.subi %[[TRIP_VAR]], %[[ONE_1]] : i32 -! NSW: fir.store %[[TRIP_VAR_NEXT]] to %[[TRIP_VAR_REF]] : !fir.ref -! NSW: %[[LOOP_VAR:.*]] = fir.load %[[LOOP_VAR_REF]] : !fir.ref -! NSW: %[[STEP_2:.*]] = arith.constant 2 : i32 -! NSW: %[[LOOP_VAR_NEXT:.*]] = arith.addi %[[LOOP_VAR]], %[[STEP_2]] overflow : i32 -! NSW: fir.store %[[LOOP_VAR_NEXT]] to %[[LOOP_VAR_REF]] : !fir.ref -! NSW: cf.br ^[[HEADER]] -! NSW: ^[[EXIT]]: -! NSW: return - ! Test a three nested unstructured loop. Three nesting is the basic case where ! we have loops that are neither innermost or outermost. subroutine nested_unstructured() @@ -215,7 +157,7 @@ subroutine nested_unstructured() ! CHECK: fir.store %[[TRIP_VAR_K_NEXT]] to %[[TRIP_VAR_K_REF]] : !fir.ref ! CHECK: %[[LOOP_VAR_K:.*]] = fir.load %[[LOOP_VAR_K_REF]] : !fir.ref ! CHECK: %[[K_STEP_2:.*]] = arith.constant 1 : i32 -! CHECK: %[[LOOP_VAR_K_NEXT:.*]] = arith.addi %[[LOOP_VAR_K]], %[[K_STEP_2]] : i32 +! CHECK: %[[LOOP_VAR_K_NEXT:.*]] = arith.addi %[[LOOP_VAR_K]], %[[K_STEP_2]] overflow : i32 ! CHECK: fir.store %[[LOOP_VAR_K_NEXT]] to %[[LOOP_VAR_K_REF]] : !fir.ref ! CHECK: cf.br ^[[HEADER_K]] ! CHECK: ^[[EXIT_K]]: @@ -225,7 +167,7 @@ subroutine nested_unstructured() ! CHECK: fir.store %[[TRIP_VAR_J_NEXT]] to %[[TRIP_VAR_J_REF]] : !fir.ref ! CHECK: %[[LOOP_VAR_J:.*]] = fir.load %[[LOOP_VAR_J_REF]] : !fir.ref ! CHECK: %[[J_STEP_2:.*]] = arith.constant 1 : i32 -! CHECK: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %[[J_STEP_2]] : i32 +! CHECK: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %[[J_STEP_2]] overflow : i32 ! CHECK: fir.store %[[LOOP_VAR_J_NEXT]] to %[[LOOP_VAR_J_REF]] : !fir.ref ! CHECK: cf.br ^[[HEADER_J]] ! CHECK: ^[[EXIT_J]]: @@ -235,96 +177,12 @@ subroutine nested_unstructured() ! CHECK: fir.store %[[TRIP_VAR_I_NEXT]] to %[[TRIP_VAR_I_REF]] : !fir.ref ! CHECK: %[[LOOP_VAR_I:.*]] = fir.load %[[LOOP_VAR_I_REF]] : !fir.ref ! CHECK: %[[I_STEP_2:.*]] = arith.constant 1 : i32 -! CHECK: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP_2]] : i32 +! CHECK: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP_2]] overflow : i32 ! CHECK: fir.store %[[LOOP_VAR_I_NEXT]] to %[[LOOP_VAR_I_REF]] : !fir.ref ! CHECK: cf.br ^[[HEADER_I]] ! CHECK: ^[[EXIT_I]]: ! CHECK: return -! NSW-LABEL: nested_unstructured -! NSW: %[[TRIP_VAR_K_REF:.*]] = fir.alloca i32 -! NSW: %[[TRIP_VAR_J_REF:.*]] = fir.alloca i32 -! NSW: %[[TRIP_VAR_I_REF:.*]] = fir.alloca i32 -! NSW: %[[LOOP_VAR_I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFnested_unstructuredEi"} -! NSW: %[[LOOP_VAR_J_REF:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFnested_unstructuredEj"} -! NSW: %[[LOOP_VAR_K_REF:.*]] = fir.alloca i32 {bindc_name = "k", uniq_name = "_QFnested_unstructuredEk"} -! NSW: %[[I_START:.*]] = arith.constant 1 : i32 -! NSW: %[[I_END:.*]] = arith.constant 100 : i32 -! NSW: %[[I_STEP:.*]] = arith.constant 1 : i32 -! NSW: %[[TMP1:.*]] = arith.subi %[[I_END]], %[[I_START]] : i32 -! NSW: %[[TMP2:.*]] = arith.addi %[[TMP1]], %[[I_STEP]] : i32 -! NSW: %[[TRIP_COUNT_I:.*]] = arith.divsi %[[TMP2]], %[[I_STEP]] : i32 -! NSW: fir.store %[[TRIP_COUNT_I]] to %[[TRIP_VAR_I_REF]] : !fir.ref -! NSW: fir.store %[[I_START]] to %[[LOOP_VAR_I_REF]] : !fir.ref -! NSW: cf.br ^[[HEADER_I:.*]] -! NSW: ^[[HEADER_I]]: -! NSW: %[[TRIP_VAR_I:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref -! NSW: %[[ZERO_1:.*]] = arith.constant 0 : i32 -! NSW: %[[COND_I:.*]] = arith.cmpi sgt, %[[TRIP_VAR_I]], %[[ZERO_1]] : i32 -! NSW: cf.cond_br %[[COND_I]], ^[[BODY_I:.*]], ^[[EXIT_I:.*]] -! NSW: ^[[BODY_I]]: -! NSW: %[[J_START:.*]] = arith.constant 1 : i32 -! NSW: %[[J_END:.*]] = arith.constant 200 : i32 -! NSW: %[[J_STEP:.*]] = arith.constant 1 : i32 -! NSW: %[[TMP3:.*]] = arith.subi %[[J_END]], %[[J_START]] : i32 -! NSW: %[[TMP4:.*]] = arith.addi %[[TMP3]], %[[J_STEP]] : i32 -! NSW: %[[TRIP_COUNT_J:.*]] = arith.divsi %[[TMP4]], %[[J_STEP]] : i32 -! NSW: fir.store %[[TRIP_COUNT_J]] to %[[TRIP_VAR_J_REF]] : !fir.ref -! NSW: fir.store %[[J_START]] to %[[LOOP_VAR_J_REF]] : !fir.ref -! NSW: cf.br ^[[HEADER_J:.*]] -! NSW: ^[[HEADER_J]]: -! NSW: %[[TRIP_VAR_J:.*]] = fir.load %[[TRIP_VAR_J_REF]] : !fir.ref -! NSW: %[[ZERO_2:.*]] = arith.constant 0 : i32 -! NSW: %[[COND_J:.*]] = arith.cmpi sgt, %[[TRIP_VAR_J]], %[[ZERO_2]] : i32 -! NSW: cf.cond_br %[[COND_J]], ^[[BODY_J:.*]], ^[[EXIT_J:.*]] -! NSW: ^[[BODY_J]]: -! NSW: %[[K_START:.*]] = arith.constant 1 : i32 -! NSW: %[[K_END:.*]] = arith.constant 300 : i32 -! NSW: %[[K_STEP:.*]] = arith.constant 1 : i32 -! NSW: %[[TMP3:.*]] = arith.subi %[[K_END]], %[[K_START]] : i32 -! NSW: %[[TMP4:.*]] = arith.addi %[[TMP3]], %[[K_STEP]] : i32 -! NSW: %[[TRIP_COUNT_K:.*]] = arith.divsi %[[TMP4]], %[[K_STEP]] : i32 -! NSW: fir.store %[[TRIP_COUNT_K]] to %[[TRIP_VAR_K_REF]] : !fir.ref -! NSW: fir.store %[[K_START]] to %[[LOOP_VAR_K_REF]] : !fir.ref -! NSW: cf.br ^[[HEADER_K:.*]] -! NSW: ^[[HEADER_K]]: -! NSW: %[[TRIP_VAR_K:.*]] = fir.load %[[TRIP_VAR_K_REF]] : !fir.ref -! NSW: %[[ZERO_2:.*]] = arith.constant 0 : i32 -! NSW: %[[COND_K:.*]] = arith.cmpi sgt, %[[TRIP_VAR_K]], %[[ZERO_2]] : i32 -! NSW: cf.cond_br %[[COND_K]], ^[[BODY_K:.*]], ^[[EXIT_K:.*]] -! NSW: ^[[BODY_K]]: -! NSW: %[[TRIP_VAR_K:.*]] = fir.load %[[TRIP_VAR_K_REF]] : !fir.ref -! NSW: %[[ONE_1:.*]] = arith.constant 1 : i32 -! NSW: %[[TRIP_VAR_K_NEXT:.*]] = arith.subi %[[TRIP_VAR_K]], %[[ONE_1]] : i32 -! NSW: fir.store %[[TRIP_VAR_K_NEXT]] to %[[TRIP_VAR_K_REF]] : !fir.ref -! NSW: %[[LOOP_VAR_K:.*]] = fir.load %[[LOOP_VAR_K_REF]] : !fir.ref -! NSW: %[[K_STEP_2:.*]] = arith.constant 1 : i32 -! NSW: %[[LOOP_VAR_K_NEXT:.*]] = arith.addi %[[LOOP_VAR_K]], %[[K_STEP_2]] overflow : i32 -! NSW: fir.store %[[LOOP_VAR_K_NEXT]] to %[[LOOP_VAR_K_REF]] : !fir.ref -! NSW: cf.br ^[[HEADER_K]] -! NSW: ^[[EXIT_K]]: -! NSW: %[[TRIP_VAR_J:.*]] = fir.load %[[TRIP_VAR_J_REF]] : !fir.ref -! NSW: %[[ONE_1:.*]] = arith.constant 1 : i32 -! NSW: %[[TRIP_VAR_J_NEXT:.*]] = arith.subi %[[TRIP_VAR_J]], %[[ONE_1]] : i32 -! NSW: fir.store %[[TRIP_VAR_J_NEXT]] to %[[TRIP_VAR_J_REF]] : !fir.ref -! NSW: %[[LOOP_VAR_J:.*]] = fir.load %[[LOOP_VAR_J_REF]] : !fir.ref -! NSW: %[[J_STEP_2:.*]] = arith.constant 1 : i32 -! NSW: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %[[J_STEP_2]] overflow : i32 -! NSW: fir.store %[[LOOP_VAR_J_NEXT]] to %[[LOOP_VAR_J_REF]] : !fir.ref -! NSW: cf.br ^[[HEADER_J]] -! NSW: ^[[EXIT_J]]: -! NSW: %[[TRIP_VAR_I:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref -! NSW: %[[ONE_1:.*]] = arith.constant 1 : i32 -! NSW: %[[TRIP_VAR_I_NEXT:.*]] = arith.subi %[[TRIP_VAR_I]], %[[ONE_1]] : i32 -! NSW: fir.store %[[TRIP_VAR_I_NEXT]] to %[[TRIP_VAR_I_REF]] : !fir.ref -! NSW: %[[LOOP_VAR_I:.*]] = fir.load %[[LOOP_VAR_I_REF]] : !fir.ref -! NSW: %[[I_STEP_2:.*]] = arith.constant 1 : i32 -! NSW: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP_2]] overflow : i32 -! NSW: fir.store %[[LOOP_VAR_I_NEXT]] to %[[LOOP_VAR_I_REF]] : !fir.ref -! NSW: cf.br ^[[HEADER_I]] -! NSW: ^[[EXIT_I]]: -! NSW: return - ! Test the existence of a structured loop inside an unstructured loop. ! Only minimal checks are inserted for the structured loop. subroutine nested_structured_in_unstructured() @@ -359,9 +217,9 @@ subroutine nested_structured_in_unstructured() ! CHECK-SAME: %{{.*}} to %{{.*}} step %[[ST:[^ ]*]] ! CHECK-SAME: iter_args(%[[J_IV:.*]] = %{{.*}}) -> (index, i32) { ! CHECK: fir.store %[[J_IV]] to %[[LOOP_VAR_J_REF]] : !fir.ref -! CHECK: %[[J_INDEX_NEXT:.*]] = arith.addi %[[J_INDEX]], %[[ST]] : index +! CHECK: %[[J_INDEX_NEXT:.*]] = arith.addi %[[J_INDEX]], %[[ST]] overflow : index ! CHECK: %[[LOOP_VAR_J:.*]] = fir.load %[[LOOP_VAR_J_REF]] : !fir.ref -! CHECK: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %{{[^ ]*}} : i32 +! CHECK: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %{{[^ ]*}} overflow : i32 ! CHECK: } ! CHECK: %[[TRIP_VAR_I:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref ! CHECK: %[[C1_3:.*]] = arith.constant 1 : i32 @@ -369,47 +227,8 @@ subroutine nested_structured_in_unstructured() ! CHECK: fir.store %[[TRIP_VAR_I_NEXT]] to %[[TRIP_VAR_I_REF]] : !fir.ref ! CHECK: %[[LOOP_VAR_I:.*]] = fir.load %[[LOOP_VAR_I_REF]] : !fir.ref ! CHECK: %[[I_STEP_2:.*]] = arith.constant 1 : i32 -! CHECK: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP_2]] : i32 +! CHECK: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP_2]] overflow : i32 ! CHECK: fir.store %[[LOOP_VAR_I_NEXT]] to %[[LOOP_VAR_I_REF]] : !fir.ref ! CHECK: cf.br ^[[HEADER]] ! CHECK: ^[[EXIT]]: ! CHECK: return - -! NSW-LABEL: nested_structured_in_unstructured -! NSW: %[[TRIP_VAR_I_REF:.*]] = fir.alloca i32 -! NSW: %[[LOOP_VAR_I_REF:.*]] = fir.alloca i32 {bindc_name = "i", uniq_name = "_QFnested_structured_in_unstructuredEi"} -! NSW: %[[LOOP_VAR_J_REF:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFnested_structured_in_unstructuredEj"} -! NSW: %[[I_START:.*]] = arith.constant 1 : i32 -! NSW: %[[I_END:.*]] = arith.constant 100 : i32 -! NSW: %[[I_STEP:.*]] = arith.constant 1 : i32 -! NSW: %[[TMP1:.*]] = arith.subi %[[I_END]], %[[I_START]] : i32 -! NSW: %[[TMP2:.*]] = arith.addi %[[TMP1]], %[[I_STEP]] : i32 -! NSW: %[[TRIP_COUNT:.*]] = arith.divsi %[[TMP2]], %[[I_STEP]] : i32 -! NSW: fir.store %[[TRIP_COUNT]] to %[[TRIP_VAR_I_REF]] : !fir.ref -! NSW: fir.store %[[I_START]] to %[[LOOP_VAR_I_REF]] : !fir.ref -! NSW: cf.br ^[[HEADER:.*]] -! NSW: ^[[HEADER]]: -! NSW: %[[TRIP_VAR:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref -! NSW: %[[ZERO:.*]] = arith.constant 0 : i32 -! NSW: %[[COND:.*]] = arith.cmpi sgt, %[[TRIP_VAR]], %[[ZERO]] : i32 -! NSW: cf.cond_br %[[COND]], ^[[BODY:.*]], ^[[EXIT:.*]] -! NSW: ^[[BODY]]: -! NSW: %{{.*}} = fir.do_loop %[[J_INDEX:[^ ]*]] = -! NSW-SAME: %{{.*}} to %{{.*}} step %[[ST:[^ ]*]] -! NSW-SAME: iter_args(%[[J_IV:.*]] = %{{.*}}) -> (index, i32) { -! NSW: fir.store %[[J_IV]] to %[[LOOP_VAR_J_REF]] : !fir.ref -! NSW: %[[J_INDEX_NEXT:.*]] = arith.addi %[[J_INDEX]], %[[ST]] overflow : index -! NSW: %[[LOOP_VAR_J:.*]] = fir.load %[[LOOP_VAR_J_REF]] : !fir.ref -! NSW: %[[LOOP_VAR_J_NEXT:.*]] = arith.addi %[[LOOP_VAR_J]], %{{[^ ]*}} overflow : i32 -! NSW: } -! NSW: %[[TRIP_VAR_I:.*]] = fir.load %[[TRIP_VAR_I_REF]] : !fir.ref -! NSW: %[[C1_3:.*]] = arith.constant 1 : i32 -! NSW: %[[TRIP_VAR_I_NEXT:.*]] = arith.subi %[[TRIP_VAR_I]], %[[C1_3]] : i32 -! NSW: fir.store %[[TRIP_VAR_I_NEXT]] to %[[TRIP_VAR_I_REF]] : !fir.ref -! NSW: %[[LOOP_VAR_I:.*]] = fir.load %[[LOOP_VAR_I_REF]] : !fir.ref -! NSW: %[[I_STEP_2:.*]] = arith.constant 1 : i32 -! NSW: %[[LOOP_VAR_I_NEXT:.*]] = arith.addi %[[LOOP_VAR_I]], %[[I_STEP_2]] overflow : i32 -! NSW: fir.store %[[LOOP_VAR_I_NEXT]] to %[[LOOP_VAR_I_REF]] : !fir.ref -! NSW: cf.br ^[[HEADER]] -! NSW: ^[[EXIT]]: -! NSW: return diff --git a/flang/test/Lower/goto-do-body.f90 b/flang/test/Lower/goto-do-body.f90 index 43afee1040914..880417c888104 100644 --- a/flang/test/Lower/goto-do-body.f90 +++ b/flang/test/Lower/goto-do-body.f90 @@ -48,7 +48,7 @@ subroutine sub1() ! CHECK: fir.store %[[TMP8]] to %[[TRIP]] : !fir.ref ! CHECK: %[[TMP9:.*]] = fir.load %[[I]] : !fir.ref ! CHECK: %[[C1_4:.*]] = arith.constant 1 : i32 -! CHECK: %[[TMP10:.*]] = arith.addi %[[TMP9]], %[[C1_4]] : i32 +! CHECK: %[[TMP10:.*]] = arith.addi %[[TMP9]], %[[C1_4]] overflow : i32 ! CHECK: fir.store %[[TMP10]] to %[[I]] : !fir.ref ! CHECK: cf.br ^[[HEADER]] end do @@ -115,7 +115,7 @@ subroutine sub2() ! CHECK: fir.store %[[TMP10]] to %[[TRIP]] : !fir.ref ! CHECK: %[[TMP11:.*]] = fir.load %[[I]] : !fir.ref ! CHECK: %[[STEP_VAL:.*]] = fir.load %[[STEP_VAR]] : !fir.ref -! CHECK: %[[TMP12:.*]] = arith.addi %[[TMP11]], %[[STEP_VAL]] : i32 +! CHECK: %[[TMP12:.*]] = arith.addi %[[TMP11]], %[[STEP_VAL]] overflow : i32 ! CHECK: fir.store %[[TMP12]] to %[[I]] : !fir.ref ! CHECK: cf.br ^[[HEADER]] end do diff --git a/flang/test/Lower/host-associated.f90 b/flang/test/Lower/host-associated.f90 index 9b4269df7bfcb..33acdff1bb74c 100644 --- a/flang/test/Lower/host-associated.f90 +++ b/flang/test/Lower/host-associated.f90 @@ -1,5 +1,5 @@ ! Test internal procedure host association lowering. -! RUN: bbc -hlfir=false %s -o - | FileCheck %s +! RUN: bbc -hlfir=false -fwrapv %s -o - | FileCheck %s ! ----------------------------------------------------------------------------- ! Test non character intrinsic scalars diff --git a/flang/test/Lower/infinite_loop.f90 b/flang/test/Lower/infinite_loop.f90 index 6942dda8d7a23..de0bee779c5b6 100644 --- a/flang/test/Lower/infinite_loop.f90 +++ b/flang/test/Lower/infinite_loop.f90 @@ -1,9 +1,11 @@ ! RUN: bbc -emit-fir -hlfir=false -o - %s | FileCheck %s ! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -o - %s | FileCheck %s -! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -flang-experimental-integer-overflow -o - %s | FileCheck %s --check-prefix=NSW +! RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fwrapv -o - %s | FileCheck %s --check-prefix=NO-NSW ! Tests for infinite loop. +! NO-NSW-NOT: overflow + subroutine empty_infinite() do end do @@ -96,10 +98,10 @@ subroutine structured_loop_in_infinite(i) ! CHECK-SAME: %[[C1_INDEX]] to %[[C10_INDEX]] step %[[C1_1]] ! CHECK-SAME: iter_args(%[[J_IV:.*]] = %[[J_LB]]) -> (index, i32) { ! CHECK: fir.store %[[J_IV]] to %[[J_REF]] : !fir.ref -! CHECK: %[[J_NEXT:.*]] = arith.addi %[[J]], %[[C1_1]] : index +! CHECK: %[[J_NEXT:.*]] = arith.addi %[[J]], %[[C1_1]] overflow : index ! CHECK: %[[J_STEPCAST:.*]] = fir.convert %[[C1_1]] : (index) -> i32 ! CHECK: %[[J_IVLOAD:.*]] = fir.load %[[J_REF]] : !fir.ref -! CHECK: %[[J_IVINC:.*]] = arith.addi %[[J_IVLOAD]], %[[J_STEPCAST]] : i32 +! CHECK: %[[J_IVINC:.*]] = arith.addi %[[J_IVLOAD]], %[[J_STEPCAST]] overflow : i32 ! CHECK: fir.result %[[J_NEXT]], %[[J_IVINC]] : index, i32 ! CHECK: } ! CHECK: fir.store %[[J_FINAL]]#1 to %[[J_REF]] : !fir.ref @@ -107,39 +109,6 @@ subroutine structured_loop_in_infinite(i) ! CHECK: ^[[RETURN]]: ! CHECK: return -! NSW-LABEL: structured_loop_in_infinite -! NSW-SAME: %[[I_REF:.*]]: !fir.ref -! NSW: %[[J_REF:.*]] = fir.alloca i32 {bindc_name = "j", uniq_name = "_QFstructured_loop_in_infiniteEj"} -! NSW: cf.br ^[[BODY1:.*]] -! NSW: ^[[BODY1]]: -! NSW: %[[I:.*]] = fir.load %[[I_REF]] : !fir.ref -! NSW: %[[C100:.*]] = arith.constant 100 : i32 -! NSW: %[[COND:.*]] = arith.cmpi sgt, %[[I]], %[[C100]] : i32 -! NSW: cf.cond_br %[[COND]], ^[[EXIT:.*]], ^[[BODY2:.*]] -! NSW: ^[[EXIT]]: -! NSW: cf.br ^[[RETURN:.*]] -! NSW: ^[[BODY2:.*]]: -! NSW: %[[C1:.*]] = arith.constant 1 : i32 -! NSW: %[[C1_INDEX:.*]] = fir.convert %[[C1]] : (i32) -> index -! NSW: %[[C10:.*]] = arith.constant 10 : i32 -! NSW: %[[C10_INDEX:.*]] = fir.convert %[[C10]] : (i32) -> index -! NSW: %[[C1_1:.*]] = arith.constant 1 : index -! NSW: %[[J_LB:.*]] = fir.convert %[[C1_INDEX]] : (index) -> i32 -! NSW: %[[J_FINAL:.*]]:2 = fir.do_loop %[[J:[^ ]*]] = -! NSW-SAME: %[[C1_INDEX]] to %[[C10_INDEX]] step %[[C1_1]] -! NSW-SAME: iter_args(%[[J_IV:.*]] = %[[J_LB]]) -> (index, i32) { -! NSW: fir.store %[[J_IV]] to %[[J_REF]] : !fir.ref -! NSW: %[[J_NEXT:.*]] = arith.addi %[[J]], %[[C1_1]] overflow : index -! NSW: %[[J_STEPCAST:.*]] = fir.convert %[[C1_1]] : (index) -> i32 -! NSW: %[[J_IVLOAD:.*]] = fir.load %[[J_REF]] : !fir.ref -! NSW: %[[J_IVINC:.*]] = arith.addi %[[J_IVLOAD]], %[[J_STEPCAST]] overflow : i32 -! NSW: fir.result %[[J_NEXT]], %[[J_IVINC]] : index, i32 -! NSW: } -! NSW: fir.store %[[J_FINAL]]#1 to %[[J_REF]] : !fir.ref -! NSW: cf.br ^[[BODY1]] -! NSW: ^[[RETURN]]: -! NSW: return - subroutine empty_infinite_in_while(i) integer :: i do while (i .gt. 50) diff --git a/flang/test/Lower/io-implied-do-fixes.f90 b/flang/test/Lower/io-implied-do-fixes.f90 index a6c115fa80ded..cd4fd43e05194 100644 --- a/flang/test/Lower/io-implied-do-fixes.f90 +++ b/flang/test/Lower/io-implied-do-fixes.f90 @@ -1,30 +1,20 @@ ! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false %s -o - | FileCheck %s -! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false -integer-overflow %s -o - | FileCheck %s --check-prefix=NSW +! RUN: bbc --use-desc-for-alloc=false -emit-fir -hlfir=false -fwrapv %s -o - | FileCheck %s --check-prefix=NO-NSW ! UNSUPPORTED: system-windows +! NO-NSW-NOT: overflow + ! CHECK-LABEL: func @_QPido1 ! CHECK: %[[J_REF_ADDR:.*]] = fir.alloca !fir.ptr {uniq_name = "_QFido1Eiptr.addr"} ! CHECK: %[[J_ADDR:.*]] = fir.load %[[J_REF_ADDR]] : !fir.ref> ! CHECK: %[[J_VAL_FINAL:.*]] = fir.do_loop %[[J_VAL:.*]] = %{{.*}} to %{{.*}} step %{{.*}} -> index { ! CHECK: %[[J_VAL_CVT1:.*]] = fir.convert %[[J_VAL]] : (index) -> i32 ! CHECK: fir.store %[[J_VAL_CVT1]] to %[[J_ADDR]] : !fir.ptr -! CHECK: %[[J_VAL_NEXT:.*]] = arith.addi %[[J_VAL]], %{{[^ ]*}} : index +! CHECK: %[[J_VAL_NEXT:.*]] = arith.addi %[[J_VAL]], %{{[^ ]*}} overflow : index ! CHECK: fir.result %[[J_VAL_NEXT]] : index ! CHECK: } ! CHECK: %[[J_VAL_CVT2:.*]] = fir.convert %[[J_VAL_FINAL]] : (index) -> i32 ! CHECK: fir.store %[[J_VAL_CVT2]] to %[[J_ADDR]] : !fir.ptr - -! NSW-LABEL: func @_QPido1 -! NSW: %[[J_REF_ADDR:.*]] = fir.alloca !fir.ptr {uniq_name = "_QFido1Eiptr.addr"} -! NSW: %[[J_ADDR:.*]] = fir.load %[[J_REF_ADDR]] : !fir.ref> -! NSW: %[[J_VAL_FINAL:.*]] = fir.do_loop %[[J_VAL:.*]] = %{{.*}} to %{{.*}} step %{{.*}} -> index { -! NSW: %[[J_VAL_CVT1:.*]] = fir.convert %[[J_VAL]] : (index) -> i32 -! NSW: fir.store %[[J_VAL_CVT1]] to %[[J_ADDR]] : !fir.ptr -! NSW: %[[J_VAL_NEXT:.*]] = arith.addi %[[J_VAL]], %{{[^ ]*}} overflow : index -! NSW: fir.result %[[J_VAL_NEXT]] : index -! NSW: } -! NSW: %[[J_VAL_CVT2:.*]] = fir.convert %[[J_VAL_FINAL]] : (index) -> i32 -! NSW: fir.store %[[J_VAL_CVT2]] to %[[J_ADDR]] : !fir.ptr subroutine ido1 integer, pointer :: iptr integer, target :: itgt @@ -38,23 +28,11 @@ subroutine ido1 ! CHECK: %[[J_VAL_FINAL:.*]] = fir.do_loop %[[J_VAL:.*]] = %{{.*}} to %{{.*}} step %{{.*}} -> index { ! CHECK: %[[J_VAL_CVT1:.*]] = fir.convert %[[J_VAL]] : (index) -> i32 ! CHECK: fir.store %[[J_VAL_CVT1]] to %[[J_ADDR]] : !fir.heap -! CHECK: %[[J_VAL_NEXT:.*]] = arith.addi %[[J_VAL]], %{{[^ ]*}} : index +! CHECK: %[[J_VAL_NEXT:.*]] = arith.addi %[[J_VAL]], %{{[^ ]*}} overflow : index ! CHECK: fir.result %[[J_VAL_NEXT]] : index ! CHECK: } ! CHECK: %[[J_VAL_CVT2:.*]] = fir.convert %[[J_VAL_FINAL]] : (index) -> i32 ! CHECK: fir.store %[[J_VAL_CVT2]] to %[[J_ADDR]] : !fir.heap - -! NSW-LABEL: func @_QPido2 -! NSW: %[[J_REF_ADDR:.*]] = fir.alloca !fir.heap {uniq_name = "_QFido2Eiptr.addr"} -! NSW: %[[J_ADDR:.*]] = fir.load %[[J_REF_ADDR]] : !fir.ref> -! NSW: %[[J_VAL_FINAL:.*]] = fir.do_loop %[[J_VAL:.*]] = %{{.*}} to %{{.*}} step %{{.*}} -> index { -! NSW: %[[J_VAL_CVT1:.*]] = fir.convert %[[J_VAL]] : (index) -> i32 -! NSW: fir.store %[[J_VAL_CVT1]] to %[[J_ADDR]] : !fir.heap -! NSW: %[[J_VAL_NEXT:.*]] = arith.addi %[[J_VAL]], %{{[^ ]*}} overflow : index -! NSW: fir.result %[[J_VAL_NEXT]] : index -! NSW: } -! NSW: %[[J_VAL_CVT2:.*]] = fir.convert %[[J_VAL_FINAL]] : (index) -> i32 -! NSW: fir.store %[[J_VAL_CVT2]] to %[[J_ADDR]] : !fir.heap subroutine ido2 integer, allocatable :: iptr allocate(iptr) @@ -69,27 +47,12 @@ subroutine ido2 ! CHECK: fir.store %[[J_VAL_CVT1]] to %[[J_ADDR]] : !fir.heap ! CHECK: %[[RES:.*]] = fir.if %[[OK]] -> (i1) { ! CHECK: } -! CHECK: %[[J_VAL_INC:.*]] = arith.addi %[[J_VAL]], %{{[^ ]*}} : index +! CHECK: %[[J_VAL_INC:.*]] = arith.addi %[[J_VAL]], %{{[^ ]*}} overflow : index ! CHECK: %[[J_VAL_NEXT:.*]] = arith.select %[[RES]], %[[J_VAL_INC]], %[[J_VAL]] : index ! CHECK: fir.result %[[J_VAL_NEXT]], %[[RES]] : index, i1 ! CHECK: } ! CHECK: %[[J_VAL_CVT2:.*]] = fir.convert %[[J_VAL_FINAL]]#0 : (index) -> i32 ! CHECK: fir.store %[[J_VAL_CVT2]] to %[[J_ADDR]] : !fir.heap {uniq_name = "_QFido3Ej.addr"} -! NSW: %[[J_ADDR:.*]] = fir.load %[[J_REF_ADDR]] : !fir.ref> -! NSW: %[[J_VAL_FINAL:.*]]:2 = fir.iterate_while (%[[J_VAL:.*]] = %{{.*}} to %{{.*}} step %{{.*}}) and (%[[OK:.*]] = {{.*}}) -> (index, i1) { -! NSW: %[[J_VAL_CVT1:.*]] = fir.convert %[[J_VAL]] : (index) -> i32 -! NSW: fir.store %[[J_VAL_CVT1]] to %[[J_ADDR]] : !fir.heap -! NSW: %[[RES:.*]] = fir.if %[[OK]] -> (i1) { -! NSW: } -! NSW: %[[J_VAL_INC:.*]] = arith.addi %[[J_VAL]], %{{[^ ]*}} overflow : index -! NSW: %[[J_VAL_NEXT:.*]] = arith.select %[[RES]], %[[J_VAL_INC]], %[[J_VAL]] : index -! NSW: fir.result %[[J_VAL_NEXT]], %[[RES]] : index, i1 -! NSW: } -! NSW: %[[J_VAL_CVT2:.*]] = fir.convert %[[J_VAL_FINAL]]#0 : (index) -> i32 -! NSW: fir.store %[[J_VAL_CVT2]] to %[[J_ADDR]] : !fir.heap ! CHECK: %[[VAL_21:.*]] = arith.constant 1 : i32 -! CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_20]], %[[VAL_21]] : i32 +! CHECK: %[[VAL_22:.*]] = arith.addi %[[VAL_20]], %[[VAL_21]] overflow : i32 ! CHECK: fir.store %[[VAL_22]] to %[[VAL_3]] : !fir.ptr ! CHECK: br ^bb1 ! CHECK: ^bb5: diff --git a/flang/test/Lower/mixed_loops.f90 b/flang/test/Lower/mixed_loops.f90 index 1aa0225129bed..991fd7aa82bb9 100644 --- a/flang/test/Lower/mixed_loops.f90 +++ b/flang/test/Lower/mixed_loops.f90 @@ -53,7 +53,7 @@ subroutine while_inside_do_loop ! CHECK: fir.store %[[TDEC]] to %[[T_REF]] ! CHECK: %[[I3:.*]] = fir.load %[[I_REF]] : !fir.ref ! CHECK: %[[C1_2:.*]] = arith.constant 1 : i32 - ! CHECK: %[[IINC:.*]] = arith.addi %[[I3]], %[[C1_2]] : i32 + ! CHECK: %[[IINC:.*]] = arith.addi %[[I3]], %[[C1_2]] overflow : i32 ! CHECK: fir.store %[[IINC]] to %[[I_REF]] : !fir.ref ! CHECK: br ^[[HDR1]] end do @@ -100,10 +100,10 @@ subroutine do_inside_while_loop ! CHECK-DAG: %[[C2:.*]] = arith.constant 2 : i32 ! CHECK: %[[JINC:.*]] = arith.muli %[[C2]], %[[J2]] : i32 ! CHECK: fir.store %[[JINC]] to %[[J_REF]] : !fir.ref - ! CHECK: %[[IINC:.*]] = arith.addi %[[IDX]], %[[C1]] : index + ! CHECK: %[[IINC:.*]] = arith.addi %[[IDX]], %[[C1]] overflow : index ! CHECK: %[[I_STEPCAST:.*]] = fir.convert %[[C1]] : (index) -> i32 ! CHECK: %[[I_IVLOAD:.*]] = fir.load %[[I_REF]] : !fir.ref - ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] : i32 + ! CHECK: %[[I_IVINC:.*]] = arith.addi %[[I_IVLOAD]], %[[I_STEPCAST]] overflow : i32 ! CHECK: fir.result %[[IINC]], %[[I_IVINC]] : index, i32 do i=8,13 j=j*2 diff --git a/flang/test/Lower/polymorphic.f90 b/flang/test/Lower/polymorphic.f90 index 8c212ce05a8c7..8c40c91bc3baa 100644 --- a/flang/test/Lower/polymorphic.f90 +++ b/flang/test/Lower/polymorphic.f90 @@ -1154,11 +1154,11 @@ program test ! CHECK-LABEL: func.func @_QQmain() attributes {fir.bindc_name = "test"} { ! CHECK: %[[ADDR_O:.*]] = fir.address_of(@_QFEo) : !fir.ref}>>>> ! CHECK: %[[BOX_NONE:.*]] = fir.convert %[[ADDR_O]] : (!fir.ref}>>>>) -> !fir.ref> -! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i64, i1, !fir.box, !fir.ref, i32) -> i32 +! CHECK: %{{.*}} = fir.call @_FortranAAllocatableAllocate(%[[BOX_NONE]], %{{.*}}, %{{.*}}, %{{.*}}, %{{.*}}) {{.*}} : (!fir.ref>, i1, !fir.box, !fir.ref, i32) -> i32 ! CHECK: %[[O:.*]] = fir.load %[[ADDR_O]] : !fir.ref}>>>> ! CHECK: %[[FIELD_INNER:.*]] = fir.field_index inner, !fir.type<_QMpolymorphic_testTouter{inner:!fir.type<_QMpolymorphic_testTp1{a:i32,b:i32}>}> ! CHECK: %[[COORD_INNER:.*]] = fir.coordinate_of %[[O]], %[[FIELD_INNER]] : (!fir.box}>>>, !fir.field) -> !fir.ref> -! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%arg1 = %{{.*}}) -> (!fir.array<5x!fir.logical<4>>) { +! CHECK: %{{.*}} = fir.do_loop %{{.*}} = %{{.*}} to %{{.*}} step %{{.*}} unordered iter_args(%arg1 = %9) -> (!fir.array<5x!fir.logical<4>>) { ! CHECK: %[[EMBOXED:.*]] = fir.embox %[[COORD_INNER]] : (!fir.ref>) -> !fir.class> -! CHECK: %{{.*}} = fir.call @_QMpolymorphic_testPlt(%{{.*}}, %[[EMBOXED]]) {{.*}} : (!fir.ref, !fir.class>) -> !fir.logical<4> +! CHECK: %{{.*}} = fir.call @_QMpolymorphic_testPlt(%17, %[[EMBOXED]]) {{.*}} : (!fir.ref, !fir.class>) -> !fir.logical<4> ! CHECK: } diff --git a/flang/test/Lower/vector-subscript-io.f90 b/flang/test/Lower/vector-subscript-io.f90 index 129e3ee1206c0..372130fd09907 100644 --- a/flang/test/Lower/vector-subscript-io.f90 +++ b/flang/test/Lower/vector-subscript-io.f90 @@ -30,7 +30,7 @@ subroutine simple(x, y) ! CHECK: %[[VAL_19:.*]] = fir.array_coor %[[VAL_20]](%[[VAL_10]]) {{\[}}%[[VAL_11]]] %[[VAL_18]] : (!fir.ref>, !fir.shape<1>, !fir.slice<1>, index) -> !fir.ref ! CHECK: %[[VAL_21:.*]] = fir.convert %[[VAL_19]] : (!fir.ref) -> !fir.ref ! CHECK: %[[VAL_22:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_9]], %[[VAL_21]], %[[VAL_3]]) {{.*}}: (!fir.ref, !fir.ref, i32) -> i1 -! CHECK: %[[VAL_23:.*]] = arith.addi %[[VAL_12]], %[[VAL_6]] : index +! CHECK: %[[VAL_23:.*]] = arith.addi %[[VAL_12]], %[[VAL_6]] overflow : index ! CHECK: %[[VAL_24:.*]] = arith.subi %[[VAL_13]], %[[VAL_6]] : index ! CHECK: cf.br ^bb1(%[[VAL_23]], %[[VAL_24]] : index, index) ! CHECK: ^bb3: @@ -79,7 +79,7 @@ integer function get_substcript() ! CHECK: %[[VAL_49:.*]] = fir.convert %[[VAL_48]] : (i32) -> index ! CHECK: %[[VAL_50:.*]] = fir.array_coor %[[VAL_51]] {{\[}}%[[VAL_42]]] %[[VAL_46]], %[[VAL_49]] : (!fir.box>, !fir.slice<2>, index, index) -> !fir.ref ! CHECK: %[[VAL_52:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_34]], %[[VAL_50]]) {{.*}}: (!fir.ref, !fir.ref) -> i1 -! CHECK: %[[VAL_53:.*]] = arith.addi %[[VAL_43]], %[[VAL_30]] : index +! CHECK: %[[VAL_53:.*]] = arith.addi %[[VAL_43]], %[[VAL_30]] overflow : index ! CHECK: %[[VAL_54:.*]] = arith.subi %[[VAL_44]], %[[VAL_30]] : index ! CHECK: cf.br ^bb1(%[[VAL_53]], %[[VAL_54]] : index, index) ! CHECK: ^bb3: @@ -122,7 +122,7 @@ subroutine with_assumed_shapes(x, y) ! CHECK: %[[VAL_77:.*]] = fir.array_coor %[[VAL_78]] {{\[}}%[[VAL_70]]] %[[VAL_76]] : (!fir.box>, !fir.slice<1>, index) -> !fir.ref ! CHECK: %[[VAL_79:.*]] = fir.convert %[[VAL_77]] : (!fir.ref) -> !fir.ref ! CHECK: %[[VAL_80:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_67]], %[[VAL_79]], %[[VAL_62]]) {{.*}}: (!fir.ref, !fir.ref, i32) -> i1 -! CHECK: %[[VAL_81:.*]] = arith.addi %[[VAL_71]], %[[VAL_64]] : index +! CHECK: %[[VAL_81:.*]] = arith.addi %[[VAL_71]], %[[VAL_64]] overflow : index ! CHECK: %[[VAL_82:.*]] = arith.subi %[[VAL_72]], %[[VAL_64]] : index ! CHECK: cf.br ^bb1(%[[VAL_81]], %[[VAL_82]] : index, index) ! CHECK: ^bb3: @@ -162,7 +162,7 @@ subroutine lower_bounds(x, y) ! CHECK: %[[VAL_107:.*]] = fir.array_coor %[[VAL_108]](%[[VAL_97]]) {{\[}}%[[VAL_99]]] %[[VAL_91]], %[[VAL_106]] : (!fir.ref>, !fir.shapeshift<2>, !fir.slice<2>, index, index) -> !fir.ref ! CHECK: %[[VAL_109:.*]] = fir.convert %[[VAL_107]] : (!fir.ref) -> !fir.ref ! CHECK: %[[VAL_110:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_96]], %[[VAL_109]], %[[VAL_90]]) {{.*}}: (!fir.ref, !fir.ref, i32) -> i1 -! CHECK: %[[VAL_111:.*]] = arith.addi %[[VAL_100]], %[[VAL_93]] : index +! CHECK: %[[VAL_111:.*]] = arith.addi %[[VAL_100]], %[[VAL_93]] overflow : index ! CHECK: %[[VAL_112:.*]] = arith.subi %[[VAL_101]], %[[VAL_93]] : index ! CHECK: cf.br ^bb1(%[[VAL_111]], %[[VAL_112]] : index, index) ! CHECK: ^bb3: @@ -202,11 +202,11 @@ subroutine two_vectors(x, y1, y2) ! CHECK: %[[VAL_138:.*]] = fir.convert %[[VAL_137]] : (i32) -> index ! CHECK: %[[VAL_139:.*]] = fir.array_coor %[[VAL_140]](%[[VAL_123]]) {{\[}}%[[VAL_124]]] %[[VAL_134]], %[[VAL_138]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref ! CHECK: %[[VAL_141:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_122]], %[[VAL_139]]) {{.*}}: (!fir.ref, !fir.ref) -> i1 -! CHECK: %[[VAL_142:.*]] = arith.addi %[[VAL_128]], %[[VAL_119]] : index +! CHECK: %[[VAL_142:.*]] = arith.addi %[[VAL_128]], %[[VAL_119]] overflow : index ! CHECK: %[[VAL_143:.*]] = arith.subi %[[VAL_129]], %[[VAL_119]] : index ! CHECK: cf.br ^bb2(%[[VAL_142]], %[[VAL_143]] : index, index) ! CHECK: ^bb4: -! CHECK: %[[VAL_144:.*]] = arith.addi %[[VAL_125]], %[[VAL_119]] : index +! CHECK: %[[VAL_144:.*]] = arith.addi %[[VAL_125]], %[[VAL_119]] overflow : index ! CHECK: %[[VAL_145:.*]] = arith.subi %[[VAL_126]], %[[VAL_119]] : index ! CHECK: cf.br ^bb1(%[[VAL_144]], %[[VAL_145]] : index, index) ! CHECK: ^bb5: @@ -245,11 +245,11 @@ subroutine triplets_and_vector(x, y) ! CHECK: %[[VAL_169:.*]] = fir.array_coor %[[VAL_170]](%[[VAL_157]]) {{\[}}%[[VAL_158]]] %[[VAL_162]], %[[VAL_168]] : (!fir.ref>>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref> ! CHECK: %[[VAL_171:.*]] = fir.convert %[[VAL_169]] : (!fir.ref>) -> !fir.ref ! CHECK: %[[VAL_172:.*]] = fir.call @_FortranAioInputComplex32(%[[VAL_156]], %[[VAL_171]]) {{.*}}: (!fir.ref, !fir.ref) -> i1 -! CHECK: %[[VAL_173:.*]] = arith.addi %[[VAL_162]], %[[VAL_153]] : index +! CHECK: %[[VAL_173:.*]] = arith.addi %[[VAL_162]], %[[VAL_153]] overflow : index ! CHECK: %[[VAL_174:.*]] = arith.subi %[[VAL_163]], %[[VAL_153]] : index ! CHECK: cf.br ^bb2(%[[VAL_173]], %[[VAL_174]] : index, index) ! CHECK: ^bb4: -! CHECK: %[[VAL_175:.*]] = arith.addi %[[VAL_159]], %[[VAL_153]] : index +! CHECK: %[[VAL_175:.*]] = arith.addi %[[VAL_159]], %[[VAL_153]] overflow : index ! CHECK: %[[VAL_176:.*]] = arith.subi %[[VAL_160]], %[[VAL_153]] : index ! CHECK: cf.br ^bb1(%[[VAL_175]], %[[VAL_176]] : index, index) ! CHECK: ^bb5: @@ -287,7 +287,7 @@ subroutine simple_char(x, y) ! CHECK: %[[VAL_200:.*]] = fir.convert %[[VAL_199]] : (!fir.ref>) -> !fir.ref ! CHECK: %[[VAL_201:.*]] = fir.convert %[[VAL_184]]#1 : (index) -> i64 ! CHECK: %[[VAL_202:.*]] = fir.call @_FortranAioInputAscii(%[[VAL_189]], %[[VAL_200]], %[[VAL_201]]) {{.*}}: (!fir.ref, !fir.ref, i64) -> i1 -! CHECK: %[[VAL_203:.*]] = arith.addi %[[VAL_192]], %[[VAL_183]] : index +! CHECK: %[[VAL_203:.*]] = arith.addi %[[VAL_192]], %[[VAL_183]] overflow : index ! CHECK: %[[VAL_204:.*]] = arith.subi %[[VAL_193]], %[[VAL_183]] : index ! CHECK: cf.br ^bb1(%[[VAL_203]], %[[VAL_204]] : index, index) ! CHECK: ^bb3: @@ -333,7 +333,7 @@ subroutine substring(x, y, i, j) ! CHECK: %[[VAL_238:.*]] = fir.convert %[[VAL_233]] : (!fir.ref>) -> !fir.ref ! CHECK: %[[VAL_239:.*]] = fir.convert %[[VAL_237]] : (index) -> i64 ! CHECK: %[[VAL_240:.*]] = fir.call @_FortranAioInputAscii(%[[VAL_213]], %[[VAL_238]], %[[VAL_239]]) {{.*}}: (!fir.ref, !fir.ref, i64) -> i1 -! CHECK: %[[VAL_241:.*]] = arith.addi %[[VAL_221]], %[[VAL_210]] : index +! CHECK: %[[VAL_241:.*]] = arith.addi %[[VAL_221]], %[[VAL_210]] overflow : index ! CHECK: %[[VAL_242:.*]] = arith.subi %[[VAL_222]], %[[VAL_210]] : index ! CHECK: cf.br ^bb1(%[[VAL_241]], %[[VAL_242]] : index, index) ! CHECK: ^bb3: @@ -366,7 +366,7 @@ subroutine complex_part(z, y) ! CHECK: %[[VAL_260:.*]] = fir.convert %[[VAL_259]] : (i32) -> index ! CHECK: %[[VAL_261:.*]] = fir.array_coor %[[VAL_262]] {{\[}}%[[VAL_254]]] %[[VAL_260]] : (!fir.box>>, !fir.slice<1>, index) -> !fir.ref ! CHECK: %[[VAL_263:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_251]], %[[VAL_261]]) {{.*}}: (!fir.ref, !fir.ref) -> i1 -! CHECK: %[[VAL_264:.*]] = arith.addi %[[VAL_255]], %[[VAL_248]] : index +! CHECK: %[[VAL_264:.*]] = arith.addi %[[VAL_255]], %[[VAL_248]] overflow : index ! CHECK: %[[VAL_265:.*]] = arith.subi %[[VAL_256]], %[[VAL_248]] : index ! CHECK: cf.br ^bb1(%[[VAL_264]], %[[VAL_265]] : index, index) ! CHECK: ^bb3: @@ -414,7 +414,7 @@ subroutine simple_derived(x, y) ! CHECK: %[[VAL_288:.*]] = fir.embox %[[VAL_286]] : (!fir.ref}>>) -> !fir.box}>> ! CHECK: %[[VAL_289:.*]] = fir.convert %[[VAL_288]] : (!fir.box}>>) -> !fir.box ! CHECK: %[[VAL_290:.*]] = fir.call @_FortranAioInputDerivedType(%[[VAL_276]], %[[VAL_289]], {{.*}}) {{.*}}: (!fir.ref, !fir.box, !fir.ref) -> i1 -! CHECK: %[[VAL_291:.*]] = arith.addi %[[VAL_279]], %[[VAL_273]] : index +! CHECK: %[[VAL_291:.*]] = arith.addi %[[VAL_279]], %[[VAL_273]] overflow : index ! CHECK: %[[VAL_292:.*]] = arith.subi %[[VAL_280]], %[[VAL_273]] : index ! CHECK: cf.br ^bb1(%[[VAL_291]], %[[VAL_292]] : index, index) ! CHECK: ^bb3: @@ -463,11 +463,11 @@ subroutine with_path(b, i) ! CHECK: %[[VAL_325:.*]] = fir.array_coor %[[VAL_326:.*]](%[[VAL_313]]) {{\[}}%[[VAL_315]]] %[[VAL_301]], %[[VAL_324]], %[[VAL_316]] : (!fir.box}>>}>>>, !fir.shift<3>, !fir.slice<3>, index, index, index) -> !fir.ref ! CHECK: %[[VAL_327:.*]] = fir.convert %[[VAL_325]] : (!fir.ref) -> !fir.ref ! CHECK: %[[VAL_328:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_308]], %[[VAL_327]], %[[VAL_302]]) {{.*}}: (!fir.ref, !fir.ref, i32) -> i1 -! CHECK: %[[VAL_329:.*]] = arith.addi %[[VAL_319]], %[[VAL_305]] : index +! CHECK: %[[VAL_329:.*]] = arith.addi %[[VAL_319]], %[[VAL_305]] overflow : index ! CHECK: %[[VAL_330:.*]] = arith.subi %[[VAL_320]], %[[VAL_305]] : index ! CHECK: cf.br ^bb2(%[[VAL_329]], %[[VAL_330]] : index, index) ! CHECK: ^bb4: -! CHECK: %[[VAL_331:.*]] = arith.addi %[[VAL_316]], %[[VAL_305]] : index +! CHECK: %[[VAL_331:.*]] = arith.addi %[[VAL_316]], %[[VAL_305]] overflow : index ! CHECK: %[[VAL_332:.*]] = arith.subi %[[VAL_317]], %[[VAL_305]] : index ! CHECK: cf.br ^bb1(%[[VAL_331]], %[[VAL_332]] : index, index) ! CHECK: ^bb5: @@ -505,7 +505,7 @@ subroutine simple_iostat(x, y, j, stat) ! CHECK: %[[VAL_355:.*]] = fir.convert %[[VAL_354]] : (i32) -> index ! CHECK: %[[VAL_356:.*]] = fir.array_coor %[[VAL_357]] {{\[}}%[[VAL_347]]] %[[VAL_355]] : (!fir.box>, !fir.slice<1>, index) -> !fir.ref ! CHECK: %[[VAL_358:.*]] = fir.call @_FortranAioInputReal32(%[[VAL_343]], %[[VAL_356]]) {{.*}}: (!fir.ref, !fir.ref) -> i1 -! CHECK: %[[VAL_359:.*]] = arith.addi %[[VAL_349]], %[[VAL_338]] : index +! CHECK: %[[VAL_359:.*]] = arith.addi %[[VAL_349]], %[[VAL_338]] overflow : index ! CHECK: cf.br ^bb1(%[[VAL_359]], %[[VAL_358]] : index, i1) ! CHECK: ^bb3: ! CHECK: cf.cond_br %[[VAL_350]], ^bb4, ^bb5 @@ -568,10 +568,10 @@ subroutine iostat_in_io_loop(k, j, stat) ! CHECK: %[[VAL_399:.*]] = fir.array_coor %[[VAL_400]](%[[VAL_387]]) {{\[}}%[[VAL_389]]] %[[VAL_394]], %[[VAL_398]] : (!fir.ref>, !fir.shape<2>, !fir.slice<2>, index, index) -> !fir.ref ! CHECK: %[[VAL_401:.*]] = fir.convert %[[VAL_399]] : (!fir.ref) -> !fir.ref ! CHECK: %[[VAL_402:.*]] = fir.call @_FortranAioInputInteger(%[[VAL_378]], %[[VAL_401]], %[[VAL_374]]) {{.*}}: (!fir.ref, !fir.ref, i32) -> i1 -! CHECK: %[[VAL_403:.*]] = arith.addi %[[VAL_390]], %[[VAL_371]] : index +! CHECK: %[[VAL_403:.*]] = arith.addi %[[VAL_390]], %[[VAL_371]] overflow : index ! CHECK: cf.br ^bb4(%[[VAL_403]], %[[VAL_402]] : index, i1) ! CHECK: ^bb6(%[[VAL_404:.*]]: i1): -! CHECK: %[[VAL_405:.*]] = arith.addi %[[VAL_380]], %[[VAL_371]] : index +! CHECK: %[[VAL_405:.*]] = arith.addi %[[VAL_380]], %[[VAL_371]] overflow : index ! CHECK: cf.br ^bb1(%[[VAL_405]], %[[VAL_404]] : index, i1) ! CHECK: ^bb7: ! CHECK: %[[VAL_406:.*]] = fir.convert %[[VAL_380]] : (index) -> i32 diff --git a/flang/test/Parser/OpenMP/atomic-unparse.f90 b/flang/test/Parser/OpenMP/atomic-unparse.f90 index 64fa79fb1d1a2..16dc7a1a92bf9 100644 --- a/flang/test/Parser/OpenMP/atomic-unparse.f90 +++ b/flang/test/Parser/OpenMP/atomic-unparse.f90 @@ -165,6 +165,20 @@ program main i = j end if + +!$omp atomic compare fail(relaxed) + if (i .eq. k) then + i = j + end if +!$omp atomic fail(relaxed) compare + if (i .eq. k) then + i = j + end if +!$omp atomic fail(relaxed) compare acquire + if (i .eq. k) then + i = j + end if + !ATOMIC !$omp atomic i = j @@ -262,6 +276,9 @@ end program main !CHECK: !$OMP ATOMIC COMPARE ACQUIRE !CHECK: !$OMP ATOMIC RELAXED COMPARE !CHECK: !$OMP ATOMIC COMPARE RELAXED +!CHECK: !$OMP ATOMIC COMPARE FAIL(RELAXED) +!CHECK: !$OMP ATOMIC FAIL(RELAXED) COMPARE +!CHECK: !$OMP ATOMIC FAIL(RELAXED) COMPARE ACQUIRE !ATOMIC !CHECK: !$OMP ATOMIC @@ -270,3 +287,5 @@ end program main !CHECK: !$OMP ATOMIC ACQ_REL !CHECK: !$OMP ATOMIC ACQUIRE !CHECK: !$OMP ATOMIC RELAXED + + diff --git a/flang/test/Parser/OpenMP/error-unparse.f90 b/flang/test/Parser/OpenMP/error-unparse.f90 new file mode 100644 index 0000000000000..fce5d8cf22863 --- /dev/null +++ b/flang/test/Parser/OpenMP/error-unparse.f90 @@ -0,0 +1,23 @@ +! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-unparse-no-sema %s 2>&1 | FileCheck %s +! RUN: %flang_fc1 -fopenmp-version=51 -fopenmp -fdebug-dump-parse-tree-no-sema %s 2>&1 | FileCheck %s --check-prefix="PARSE-TREE" +program main + character(*), parameter :: message = "This is an error" + !CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(WARNING) MESSAGE("some message here") + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct + !PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Compilation + !PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Warning + !PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> LiteralConstant -> CharLiteralConstant + !$omp error at(compilation) severity(warning) message("some message here") + !CHECK: !$OMP ERROR AT(COMPILATION) SEVERITY(FATAL) MESSAGE(message) + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct + !PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Compilation + !PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Fatal + !PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> Designator -> DataRef -> Name = 'message' + !$omp error at(compilation) severity(fatal) message(message) + !CHECK: !$OMP ERROR AT(EXECUTION) SEVERITY(FATAL) MESSAGE(message) + !PARSE-TREE: ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPErrorConstruct + !PARSE-TREE: OmpClauseList -> OmpClause -> At -> OmpAtClause -> ActionTime = Execution + !PARSE-TREE: OmpClause -> Severity -> OmpSeverityClause -> Severity = Fatal + !PARSE-TREE: OmpClause -> Message -> OmpMessageClause -> Expr -> Designator -> DataRef -> Name = 'message' + !$omp error at(EXECUTION) severity(fatal) message(message) +end program main diff --git a/flang/test/Parser/OpenMP/in-reduction-clause.f90 b/flang/test/Parser/OpenMP/in-reduction-clause.f90 index ab26ca2d9300f..8a0bede62f03f 100644 --- a/flang/test/Parser/OpenMP/in-reduction-clause.f90 +++ b/flang/test/Parser/OpenMP/in-reduction-clause.f90 @@ -5,16 +5,16 @@ subroutine omp_in_reduction_taskgroup() integer :: z, i - !CHECK: !$OMP TASKGROUP TASK_REDUCTION(+:z) + !CHECK: !$OMP TASKGROUP TASK_REDUCTION(+: z) !$omp taskgroup task_reduction(+:z) - !CHECK-NEXT: !$OMP TASK IN_REDUCTION(+:z) + !CHECK-NEXT: !$OMP TASK IN_REDUCTION(+: z) !$omp task in_reduction(+:z) !CHECK-NEXT: z=z+5_4 z = z + 5 !CHECK-NEXT: !$OMP END TASK !$omp end task - !CHECK-NEXT: !$OMP TASKLOOP IN_REDUCTION(+:z) + !CHECK-NEXT: !$OMP TASKLOOP IN_REDUCTION(+: z) !$omp taskloop in_reduction(+:z) !CHECK-NEXT: DO i=1_4,10_4 do i=1,10 @@ -31,7 +31,7 @@ end subroutine omp_in_reduction_taskgroup !PARSE-TREE: OpenMPConstruct -> OpenMPBlockConstruct !PARSE-TREE-NEXT: OmpBeginBlockDirective !PARSE-TREE-NEXT: OmpBlockDirective -> llvm::omp::Directive = taskgroup -!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> TaskReduction -> OmpReductionClause +!PARSE-TREE-NEXT: OmpClauseList -> OmpClause -> TaskReduction -> OmpTaskReductionClause !PARSE-TREE: OpenMPConstruct -> OpenMPBlockConstruct !PARSE-TREE-NEXT: OmpBeginBlockDirective @@ -49,9 +49,9 @@ end subroutine omp_in_reduction_taskgroup subroutine omp_in_reduction_parallel() integer :: z - !CHECK: !$OMP PARALLEL REDUCTION(+:z) + !CHECK: !$OMP PARALLEL REDUCTION(+: z) !$omp parallel reduction(+:z) - !CHECK-NEXT: !$OMP TASKLOOP SIMD IN_REDUCTION(+:z) + !CHECK-NEXT: !$OMP TASKLOOP SIMD IN_REDUCTION(+: z) !$omp taskloop simd in_reduction(+:z) !CHECK-NEXT: DO i=1_4,10_4 do i=1,10 diff --git a/flang/test/Parser/OpenMP/linear-clause.f90 b/flang/test/Parser/OpenMP/linear-clause.f90 new file mode 100644 index 0000000000000..5f031b0694149 --- /dev/null +++ b/flang/test/Parser/OpenMP/linear-clause.f90 @@ -0,0 +1,117 @@ +!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=52 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s +!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=52 %s | FileCheck --check-prefix="PARSE-TREE" %s + +subroutine f00(x) + integer :: x + !$omp do linear(x) + do x = 1, 10 + enddo + !$omp end do +end + +!UNPARSE: SUBROUTINE f00 (x) +!UNPARSE: INTEGER x +!UNPARSE: !$OMP DO LINEAR(x) +!UNPARSE: DO x=1_4,10_4 +!UNPARSE: END DO +!UNPARSE: !$OMP END DO +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpBeginLoopDirective +!PARSE-TREE: | OmpLoopDirective -> llvm::omp::Directive = do +!PARSE-TREE: | OmpClauseList -> OmpClause -> Linear -> OmpLinearClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | bool = 'true' +!PARSE-TREE: DoConstruct + +subroutine f01(x) + integer :: x + !$omp do linear(x : 2) + do x = 1, 10 + enddo + !$omp end do +end + +!UNPARSE: SUBROUTINE f01 (x) +!UNPARSE: INTEGER x +!UNPARSE: !$OMP DO LINEAR(x: 2_4) +!UNPARSE: DO x=1_4,10_4 +!UNPARSE: END DO +!UNPARSE: !$OMP END DO +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpBeginLoopDirective +!PARSE-TREE: | OmpLoopDirective -> llvm::omp::Directive = do +!PARSE-TREE: | OmpClauseList -> OmpClause -> Linear -> OmpLinearClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | Modifier -> OmpStepSimpleModifier -> Scalar -> Integer -> Expr = '2_4' +!PARSE-TREE: | | | LiteralConstant -> IntLiteralConstant = '2' +!PARSE-TREE: | | bool = 'true' +!PARSE-TREE: DoConstruct + +subroutine f02(x) + integer :: x + !$omp do linear(x : step(3)) + do x = 1, 10 + enddo + !$omp end do +end + +!UNPARSE: SUBROUTINE f02 (x) +!UNPARSE: INTEGER x +!UNPARSE: !$OMP DO LINEAR(x: STEP(3_4)) +!UNPARSE: DO x=1_4,10_4 +!UNPARSE: END DO +!UNPARSE: !$OMP END DO +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpBeginLoopDirective +!PARSE-TREE: | OmpLoopDirective -> llvm::omp::Directive = do +!PARSE-TREE: | OmpClauseList -> OmpClause -> Linear -> OmpLinearClause +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | Modifier -> OmpStepComplexModifier -> Scalar -> Integer -> Expr = '3_4' +!PARSE-TREE: | | | LiteralConstant -> IntLiteralConstant = '3' +!PARSE-TREE: | | bool = 'true' +!PARSE-TREE: DoConstruct + +subroutine f03(x) + integer :: x + !$omp declare simd linear(x : uval) +end + +!UNPARSE: SUBROUTINE f03 (x) +!UNPARSE: INTEGER x +!UNPARSE: !$OMP DECLARE SIMD LINEAR(x: UVAL) +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: SpecificationPart +![...] +!PARSE-TREE: | DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareSimdConstruct +!PARSE-TREE: | | Verbatim +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Linear -> OmpLinearClause +!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | | Modifier -> OmpLinearModifier -> Value = Uval +!PARSE-TREE: | | | bool = 'true' +!PARSE-TREE: ExecutionPart -> Block + +subroutine f04(x) + integer :: x + !$omp declare simd linear(x : uval, step(3)) +end + +!UNPARSE: SUBROUTINE f04 (x) +!UNPARSE: INTEGER x +!UNPARSE: !$OMP DECLARE SIMD LINEAR(x: UVAL, STEP(3_4)) +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: SpecificationPart +![...] +!PARSE-TREE: | DeclarationConstruct -> SpecificationConstruct -> OpenMPDeclarativeConstruct -> OpenMPDeclareSimdConstruct +!PARSE-TREE: | | Verbatim +!PARSE-TREE: | | OmpClauseList -> OmpClause -> Linear -> OmpLinearClause +!PARSE-TREE: | | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: | | | Modifier -> OmpLinearModifier -> Value = Uval +!PARSE-TREE: | | | Modifier -> OmpStepComplexModifier -> Scalar -> Integer -> Expr = '3_4' +!PARSE-TREE: | | | | LiteralConstant -> IntLiteralConstant = '3' +!PARSE-TREE: | | | bool = 'true' +!PARSE-TREE: ExecutionPart -> Block diff --git a/flang/test/Parser/OpenMP/reduction-modifier.f90 b/flang/test/Parser/OpenMP/reduction-modifier.f90 index 64cd452e839e7..56303af66395e 100644 --- a/flang/test/Parser/OpenMP/reduction-modifier.f90 +++ b/flang/test/Parser/OpenMP/reduction-modifier.f90 @@ -4,7 +4,7 @@ subroutine foo() integer :: i, j j = 0 -! CHECK: !$OMP DO REDUCTION(TASK, *:j) +! CHECK: !$OMP DO REDUCTION(TASK, *: j) ! PARSE-TREE: | | ExecutionPartConstruct -> ExecutableConstruct -> OpenMPConstruct -> OpenMPLoopConstruct ! PARSE-TREE: | | | OmpBeginLoopDirective ! PARSE-TREE: | | | | OmpLoopDirective -> llvm::omp::Directive = do diff --git a/flang/test/Parser/OpenMP/task-reduction-clause.f90 b/flang/test/Parser/OpenMP/task-reduction-clause.f90 new file mode 100644 index 0000000000000..248ff7918dbe5 --- /dev/null +++ b/flang/test/Parser/OpenMP/task-reduction-clause.f90 @@ -0,0 +1,23 @@ +!RUN: %flang_fc1 -fdebug-unparse -fopenmp -fopenmp-version=50 %s | FileCheck --ignore-case --check-prefix="UNPARSE" %s +!RUN: %flang_fc1 -fdebug-dump-parse-tree -fopenmp -fopenmp-version=50 %s | FileCheck --check-prefix="PARSE-TREE" %s + +subroutine f00 + integer :: x +!$omp taskgroup task_reduction(+: x) + x = x + 1 +!$omp end taskgroup +end + +!UNPARSE: SUBROUTINE f00 +!UNPARSE: INTEGER x +!UNPARSE: !$OMP TASKGROUP TASK_REDUCTION(+: x) +!UNPARSE: x=x+1_4 +!UNPARSE: !$OMP END TASKGROUP +!UNPARSE: END SUBROUTINE + +!PARSE-TREE: OmpBeginBlockDirective +!PARSE-TREE: | OmpBlockDirective -> llvm::omp::Directive = taskgroup +!PARSE-TREE: | OmpClauseList -> OmpClause -> TaskReduction -> OmpTaskReductionClause +!PARSE-TREE: | | Modifier -> OmpReductionIdentifier -> DefinedOperator -> IntrinsicOperator = Add +!PARSE-TREE: | | OmpObjectList -> OmpObject -> Designator -> DataRef -> Name = 'x' +!PARSE-TREE: Block diff --git a/flang/test/Preprocessing/directive-contin-with-pp.F90 b/flang/test/Preprocessing/directive-contin-with-pp.F90 index 544c6619f6b53..6e84c2bde52f9 100644 --- a/flang/test/Preprocessing/directive-contin-with-pp.F90 +++ b/flang/test/Preprocessing/directive-contin-with-pp.F90 @@ -70,13 +70,13 @@ subroutine s3 !CHECK: !DIR$ IGNORE_TKR x5 !CHECK: !DIR$ IGNORE_TKR x6 !CHECK: STOP 1_4 -!CHECK: !$OMP PARALLEL DO REDUCTION(+:x) +!CHECK: !$OMP PARALLEL DO REDUCTION(+: x) !CHECK: DO j1=1_4,n !CHECK: END DO -!CHECK: !$OMP PARALLEL DO REDUCTION(+:x) +!CHECK: !$OMP PARALLEL DO REDUCTION(+: x) !CHECK: DO j2=1_4,n !CHECK: END DO -!CHECK: !$OMP PARALLEL DO REDUCTION(+:x) +!CHECK: !$OMP PARALLEL DO REDUCTION(+: x) !CHECK: DO j3=1_4,n !CHECK: END DO !CHECK: END SUBROUTINE diff --git a/flang/test/Preprocessing/pp132.f90 b/flang/test/Preprocessing/pp132.f90 index 418defb2d553c..76ffa3e21c137 100644 --- a/flang/test/Preprocessing/pp132.f90 +++ b/flang/test/Preprocessing/pp132.f90 @@ -1,9 +1,10 @@ -! RUN: %flang -E -fopenmp -fopenacc %s 2>&1 | FileCheck %s -! CHECK: !$OMP parallel default(shared) private(super_very_long_name_for_the_va& -! CHECK: !$OMP&riable) -! CHECK: !$acc data copyin(super_very_long_name_for_the_variable, another_super& -! CHECK: !$acc&_wordy_variable_to_test) -! Test correct continuations in compiler directives +! RUN: %flang -E -fopenmp -fopenacc %s 2>&1 | FileCheck --strict-whitespace %s +! CHECK: {{^}}!$OMP parallel default(shared) private(super_very_long_name_for_the_va& +! CHECK-NEXT: {{^}}!$OMP&riable) +! CHECK: {{^}}!$acc data copyin(super_very_long_name_for_the_variable, another_super& +! CHECK-NEXT: {{^}}!$acc&_wordy_variable_to_test) +! CHECK: {{^}}!$OMP something something +! Test correct continuations in compiler directives and left-alignment of sentinels subroutine foo integer :: super_very_long_name_for_the_variable integer :: another_super_wordy_variable_to_test @@ -15,4 +16,6 @@ subroutine foo !$acc data copyin(super_very_long_name_for_the_variable, another_super_wordy_variable_to_test) !$acc end data + + !$OMP something something end subroutine foo diff --git a/flang/test/Semantics/OpenMP/atomic-compare.f90 b/flang/test/Semantics/OpenMP/atomic-compare.f90 index 85644ad909107..54492bf6a22a6 100644 --- a/flang/test/Semantics/OpenMP/atomic-compare.f90 +++ b/flang/test/Semantics/OpenMP/atomic-compare.f90 @@ -35,45 +35,58 @@ if (b .eq. a) b = c !$omp end atomic + !$omp atomic hint(1) acq_rel compare fail(release) + if (c .eq. a) a = b + !$omp end atomic + + !$omp atomic compare fail(release) + if (c .eq. a) a = b + !$omp end atomic + ! Check for error conditions: - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the COMPARE directive !$omp atomic seq_cst seq_cst compare if (b .eq. c) b = a - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the COMPARE directive !$omp atomic compare seq_cst seq_cst if (b .eq. c) b = a - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the COMPARE directive !$omp atomic seq_cst compare seq_cst if (b .eq. c) b = a - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one ACQUIRE clause can appear on the COMPARE directive !$omp atomic acquire acquire compare if (b .eq. c) b = a - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one ACQUIRE clause can appear on the COMPARE directive !$omp atomic compare acquire acquire if (b .eq. c) b = a - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one ACQUIRE clause can appear on the COMPARE directive !$omp atomic acquire compare acquire if (b .eq. c) b = a - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the COMPARE directive !$omp atomic relaxed relaxed compare if (b .eq. c) b = a - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the COMPARE directive !$omp atomic compare relaxed relaxed if (b .eq. c) b = a - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the COMPARE directive !$omp atomic relaxed compare relaxed if (b .eq. c) b = a + !ERROR: More than one FAIL clause not allowed on OpenMP ATOMIC construct + !$omp atomic fail(release) compare fail(release) + if (c .eq. a) a = b + !$omp end atomic + !$omp end parallel end diff --git a/flang/test/Semantics/OpenMP/atomic01.f90 b/flang/test/Semantics/OpenMP/atomic01.f90 index 538db316f6e7f..173effe86b69c 100644 --- a/flang/test/Semantics/OpenMP/atomic01.f90 +++ b/flang/test/Semantics/OpenMP/atomic01.f90 @@ -14,193 +14,193 @@ ! At most one memory-order-clause may appear on the construct. !READ - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the READ directive !$omp atomic seq_cst seq_cst read i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the READ directive !$omp atomic read seq_cst seq_cst i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the READ directive !$omp atomic seq_cst read seq_cst i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one ACQUIRE clause can appear on the READ directive !$omp atomic acquire acquire read i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one ACQUIRE clause can appear on the READ directive !$omp atomic read acquire acquire i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one ACQUIRE clause can appear on the READ directive !$omp atomic acquire read acquire i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the READ directive !$omp atomic relaxed relaxed read i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the READ directive !$omp atomic read relaxed relaxed i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the READ directive !$omp atomic relaxed read relaxed i = j !UPDATE - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the UPDATE directive !$omp atomic seq_cst seq_cst update !ERROR: Invalid or missing operator in atomic update statement i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the UPDATE directive !$omp atomic update seq_cst seq_cst !ERROR: Invalid or missing operator in atomic update statement i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the UPDATE directive !$omp atomic seq_cst update seq_cst !ERROR: Invalid or missing operator in atomic update statement i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELEASE clause can appear on the UPDATE directive !$omp atomic release release update !ERROR: Invalid or missing operator in atomic update statement i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELEASE clause can appear on the UPDATE directive !$omp atomic update release release !ERROR: Invalid or missing operator in atomic update statement i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELEASE clause can appear on the UPDATE directive !$omp atomic release update release !ERROR: Invalid or missing operator in atomic update statement i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the UPDATE directive !$omp atomic relaxed relaxed update !ERROR: Invalid or missing operator in atomic update statement i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the UPDATE directive !$omp atomic update relaxed relaxed !ERROR: Invalid or missing operator in atomic update statement i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the UPDATE directive !$omp atomic relaxed update relaxed !ERROR: Invalid or missing operator in atomic update statement i = j !CAPTURE - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the CAPTURE directive !$omp atomic seq_cst seq_cst capture i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the CAPTURE directive !$omp atomic capture seq_cst seq_cst i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the CAPTURE directive !$omp atomic seq_cst capture seq_cst i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELEASE clause can appear on the CAPTURE directive !$omp atomic release release capture i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELEASE clause can appear on the CAPTURE directive !$omp atomic capture release release i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELEASE clause can appear on the CAPTURE directive !$omp atomic release capture release i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the CAPTURE directive !$omp atomic relaxed relaxed capture i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the CAPTURE directive !$omp atomic capture relaxed relaxed i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the CAPTURE directive !$omp atomic relaxed capture relaxed i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one ACQ_REL clause can appear on the CAPTURE directive !$omp atomic acq_rel acq_rel capture i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one ACQ_REL clause can appear on the CAPTURE directive !$omp atomic capture acq_rel acq_rel i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one ACQ_REL clause can appear on the CAPTURE directive !$omp atomic acq_rel capture acq_rel i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one ACQUIRE clause can appear on the CAPTURE directive !$omp atomic acquire acquire capture i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one ACQUIRE clause can appear on the CAPTURE directive !$omp atomic capture acquire acquire i = j j = k !$omp end atomic - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one ACQUIRE clause can appear on the CAPTURE directive !$omp atomic acquire capture acquire i = j @@ -208,57 +208,57 @@ !$omp end atomic !WRITE - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the WRITE directive !$omp atomic seq_cst seq_cst write i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the WRITE directive !$omp atomic write seq_cst seq_cst i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the WRITE directive !$omp atomic seq_cst write seq_cst i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELEASE clause can appear on the WRITE directive !$omp atomic release release write i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELEASE clause can appear on the WRITE directive !$omp atomic write release release i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELEASE clause can appear on the WRITE directive !$omp atomic release write release i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the WRITE directive !$omp atomic relaxed relaxed write i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the WRITE directive !$omp atomic write relaxed relaxed i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the WRITE directive !$omp atomic relaxed write relaxed i = j !No atomic-clause - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELAXED clause can appear on the ATOMIC directive !$omp atomic relaxed relaxed !ERROR: Invalid or missing operator in atomic update statement i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one SEQ_CST clause can appear on the ATOMIC directive !$omp atomic seq_cst seq_cst !ERROR: Invalid or missing operator in atomic update statement i = j - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !ERROR: At most one RELEASE clause can appear on the ATOMIC directive !$omp atomic release release !ERROR: Invalid or missing operator in atomic update statement diff --git a/flang/test/Semantics/OpenMP/atomic05.f90 b/flang/test/Semantics/OpenMP/atomic05.f90 index f37aabcfce06e..266268a212440 100644 --- a/flang/test/Semantics/OpenMP/atomic05.f90 +++ b/flang/test/Semantics/OpenMP/atomic05.f90 @@ -8,20 +8,20 @@ program OmpAtomic use omp_lib integer :: g, x - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !$omp atomic relaxed, seq_cst x = x + 1 - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !$omp atomic read seq_cst, relaxed x = g - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !$omp atomic write relaxed, release x = 2 * 4 - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !$omp atomic update release, seq_cst !ERROR: Invalid or missing operator in atomic update statement x = 10 - !ERROR: More than one memory order clause not allowed on OpenMP Atomic construct + !ERROR: More than one memory order clause not allowed on OpenMP ATOMIC construct !$omp atomic capture release, seq_cst x = g g = x * 10 diff --git a/flang/test/Semantics/OpenMP/clause-validity01.f90 b/flang/test/Semantics/OpenMP/clause-validity01.f90 index 66e11e4b540f0..e8114154a809b 100644 --- a/flang/test/Semantics/OpenMP/clause-validity01.f90 +++ b/flang/test/Semantics/OpenMP/clause-validity01.f90 @@ -221,11 +221,19 @@ !ERROR: Clause LINEAR is not allowed if clause ORDERED appears on the DO directive !ERROR: The parameter of the ORDERED clause must be a constant positive integer expression + !ERROR: 'b' appears in more than one data-sharing clause on the same OpenMP directive !$omp do ordered(1-1) private(b) linear(b) linear(a) do i = 1, N a = 3.14 enddo + !ERROR: Clause LINEAR is not allowed if clause ORDERED appears on the DO directive + !ERROR: The parameter of the ORDERED clause must be a constant positive integer expression + !$omp do ordered(1-1) linear(a) + do i = 1, N + a = 3.14 + enddo + !ERROR: The parameter of the ORDERED clause must be greater than or equal to the parameter of the COLLAPSE clause !$omp do collapse(num-14) ordered(1) do i = 1, N diff --git a/flang/test/Semantics/OpenMP/declarative-directive01.f90 b/flang/test/Semantics/OpenMP/declarative-directive01.f90 index 8d6762b87adb9..17dc50b70e542 100644 --- a/flang/test/Semantics/OpenMP/declarative-directive01.f90 +++ b/flang/test/Semantics/OpenMP/declarative-directive01.f90 @@ -23,6 +23,7 @@ end subroutine requires_2 subroutine declare_simd_1(a, b) real(8), intent(inout) :: a, b + !ERROR: 'a' in ALIGNED clause must be of type C_PTR, POINTER or ALLOCATABLE !$omp declare simd(declare_simd_1) aligned(a) a = 3.14 + b end subroutine declare_simd_1 diff --git a/flang/test/Semantics/OpenMP/from-clause-v45.f90 b/flang/test/Semantics/OpenMP/from-clause-v45.f90 index 98dff295c879d..201128fc3031c 100644 --- a/flang/test/Semantics/OpenMP/from-clause-v45.f90 +++ b/flang/test/Semantics/OpenMP/from-clause-v45.f90 @@ -2,7 +2,7 @@ subroutine f00(x) integer :: x(10) -!ERROR: Reference to x must be a contiguous object +!ERROR: Reference to 'x' must be a contiguous object !$omp target update from(x(1:10:2)) end diff --git a/flang/test/Semantics/OpenMP/in-reduction.f90 b/flang/test/Semantics/OpenMP/in-reduction.f90 new file mode 100644 index 0000000000000..1b82134b7104b --- /dev/null +++ b/flang/test/Semantics/OpenMP/in-reduction.f90 @@ -0,0 +1,70 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50 + +subroutine f00 + real :: x +!ERROR: The type of 'x' is incompatible with the reduction operator. +!$omp target in_reduction(.or.: x) +!$omp end target +end + +subroutine f01 + real :: x +!ERROR: Invalid reduction operator in IN_REDUCTION clause. +!$omp target in_reduction(.not.: x) +!$omp end target +end + +subroutine f02(p) + integer, pointer, intent(in) :: p +!ERROR: Pointer 'p' with the INTENT(IN) attribute may not appear in a IN_REDUCTION clause +!$omp target in_reduction(+: p) +!$omp end target +end + +subroutine f03 + common /c/ a, b +!ERROR: Common block names are not allowed in IN_REDUCTION clause +!$omp target in_reduction(+: /c/) +!$omp end target +end + +subroutine f04 + integer :: x(10) +!ERROR: Reference to 'x' must be a contiguous object +!$omp target in_reduction(+: x(1:10:2)) +!$omp end target +end + +subroutine f05 + integer :: x(10) +!ERROR: 'x' in IN_REDUCTION clause is a zero size array section +!$omp target in_reduction(+: x(1:0)) +!$omp end target +end + +subroutine f06 + type t + integer :: a(10) + end type + type(t) :: x +!ERROR: The base expression of an array element or section in IN_REDUCTION clause must be an identifier +!$omp target in_reduction(+: x%a(2)) +!$omp end target +end + +subroutine f07 + type t + integer :: a(10) + end type + type(t) :: x +!ERROR: The base expression of an array element or section in IN_REDUCTION clause must be an identifier +!$omp target in_reduction(+: x%a(1:10)) +!$omp end target +end + +subroutine f08 + integer :: x +!ERROR: Type parameter inquiry is not permitted in IN_REDUCTION clause +!$omp target in_reduction(+: x%kind) +!$omp end target +end diff --git a/flang/test/Semantics/OpenMP/linear-clause01.f90 b/flang/test/Semantics/OpenMP/linear-clause01.f90 new file mode 100644 index 0000000000000..d892f4cefb170 --- /dev/null +++ b/flang/test/Semantics/OpenMP/linear-clause01.f90 @@ -0,0 +1,55 @@ +! REQUIRES: openmp_runtime +! RUN: %python %S/../test_errors.py %s %flang_fc1 %openmp_flags +! OpenMP Version 5.2 +! Various checks for the linear clause +! 5.4.6 `linear` Clause + +! Case 1 +subroutine linear_clause_01(arg) + integer, intent(in) :: arg(:) + !ERROR: A modifier may not be specified in a LINEAR clause on the DO directive + !$omp do linear(uval(arg)) + do i = 1, 5 + print *, arg(i) + end do +end subroutine linear_clause_01 + +! Case 2 +subroutine linear_clause_02(arg_01, arg_02) + !WARNING: The 'modifier()' syntax is deprecated in OpenMP v5.2, use ' : modifier' instead + !ERROR: The list item 'arg_01' specified without the REF 'linear-modifier' must be of INTEGER type + !$omp declare simd linear(val(arg_01)) + real, intent(in) :: arg_01(:) + + !WARNING: The 'modifier()' syntax is deprecated in OpenMP v5.2, use ' : modifier' instead + !ERROR: The list item 'arg_02' specified without the REF 'linear-modifier' must be of INTEGER type + !ERROR: If the `linear-modifier` is REF or UVAL, the list item 'arg_02' must be a dummy argument without the VALUE attribute + !$omp declare simd linear(uval(arg_02)) + !ERROR: The type of 'arg_02' has already been implicitly declared + integer, value, intent(in) :: arg_02 + + !WARNING: The 'modifier()' syntax is deprecated in OpenMP v5.2, use ' : modifier' instead + !ERROR: The list item 'var' specified without the REF 'linear-modifier' must be of INTEGER type + !ERROR: If the `linear-modifier` is REF or UVAL, the list item 'var' must be a dummy argument without the VALUE attribute + !ERROR: The list item `var` must be a dummy argument + !ERROR: The list item `var` in a LINEAR clause must not be Cray Pointer or a variable with POINTER attribute + !$omp declare simd linear(uval(var)) + !ERROR: The type of 'var' has already been implicitly declared + integer, pointer :: var +end subroutine linear_clause_02 + +! Case 3 +subroutine linear_clause_03(arg) + integer, intent(in) :: arg + !WARNING: The 'modifier()' syntax is deprecated in OpenMP v5.2, use ' : modifier' instead + !ERROR: The list item `arg` specified with the REF 'linear-modifier' must be polymorphic variable, assumed-shape array, or a variable with the `ALLOCATABLE` attribute + !ERROR: List item 'arg' present at multiple LINEAR clauses + !ERROR: 'arg' appears in more than one data-sharing clause on the same OpenMP directive + !$omp declare simd linear(ref(arg)) linear(arg) + + integer :: i + common /cc/ i + !ERROR: The list item `i` must be a dummy argument + !ERROR: 'i' is a common block name and must not appear in an LINEAR clause + !$omp declare simd linear(i) +end subroutine linear_clause_03 diff --git a/flang/test/Semantics/OpenMP/linear-clause02.f90 b/flang/test/Semantics/OpenMP/linear-clause02.f90 new file mode 100644 index 0000000000000..695d61715820f --- /dev/null +++ b/flang/test/Semantics/OpenMP/linear-clause02.f90 @@ -0,0 +1,13 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=52 + +subroutine f00(x) + integer :: x + !WARNING: The 'modifier()' syntax is deprecated in OpenMP v5.2, use ' : modifier' instead + !$omp declare simd linear(uval(x)) +end + +subroutine f01(x) + integer :: x + !ERROR: An exclusive 'step-simple-modifier' modifier cannot be specified together with a modifier of a different type + !$omp declare simd linear(uval(x) : 2) +end diff --git a/flang/test/Semantics/OpenMP/linear-iter.f90 b/flang/test/Semantics/OpenMP/linear-iter.f90 index 8102c1a03cd37..1f40228be92ad 100644 --- a/flang/test/Semantics/OpenMP/linear-iter.f90 +++ b/flang/test/Semantics/OpenMP/linear-iter.f90 @@ -20,7 +20,7 @@ SUBROUTINE LINEAR_BAD(N) !$omp target !$omp teams - !ERROR: Variable 'j' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE` + !ERROR: Variable 'j' not allowed in LINEAR clause, only loop iterator can be specified in LINEAR clause of a construct combined with DISTRIBUTE !$omp distribute parallel do simd linear(j) do i = 1, N a = 3.14 @@ -31,8 +31,8 @@ SUBROUTINE LINEAR_BAD(N) !$omp target !$omp teams - !ERROR: Variable 'j' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE` - !ERROR: Variable 'b' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE` + !ERROR: Variable 'j' not allowed in LINEAR clause, only loop iterator can be specified in LINEAR clause of a construct combined with DISTRIBUTE + !ERROR: Variable 'b' not allowed in LINEAR clause, only loop iterator can be specified in LINEAR clause of a construct combined with DISTRIBUTE !$omp distribute parallel do simd linear(j) linear(b) do i = 1, N a = 3.14 @@ -43,8 +43,8 @@ SUBROUTINE LINEAR_BAD(N) !$omp target !$omp teams - !ERROR: Variable 'j' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE` - !ERROR: Variable 'b' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE` + !ERROR: Variable 'j' not allowed in LINEAR clause, only loop iterator can be specified in LINEAR clause of a construct combined with DISTRIBUTE + !ERROR: Variable 'b' not allowed in LINEAR clause, only loop iterator can be specified in LINEAR clause of a construct combined with DISTRIBUTE !$omp distribute parallel do simd linear(j, b) do i = 1, N a = 3.14 @@ -54,7 +54,7 @@ SUBROUTINE LINEAR_BAD(N) !$omp end target !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. - !ERROR: Variable 'j' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE` + !ERROR: Variable 'j' not allowed in LINEAR clause, only loop iterator can be specified in LINEAR clause of a construct combined with DISTRIBUTE !$omp distribute simd linear(i,j) do i = 1, N do j = 1, N @@ -64,7 +64,7 @@ SUBROUTINE LINEAR_BAD(N) !$omp end distribute simd !ERROR: `DISTRIBUTE` region has to be strictly nested inside `TEAMS` region. - !ERROR: Variable 'j' not allowed in `LINEAR` clause, only loop iterator can be specified in `LINEAR` clause of a construct combined with `DISTRIBUTE` + !ERROR: Variable 'j' not allowed in LINEAR clause, only loop iterator can be specified in LINEAR clause of a construct combined with DISTRIBUTE !$omp distribute simd linear(i,j) collapse(1) do i = 1, N do j = 1, N diff --git a/flang/test/Semantics/OpenMP/ompx-bare.f90 b/flang/test/Semantics/OpenMP/ompx-bare.f90 new file mode 100644 index 0000000000000..21a603e9a826b --- /dev/null +++ b/flang/test/Semantics/OpenMP/ompx-bare.f90 @@ -0,0 +1,30 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=51 + +subroutine test1 +!ERROR: OMPX_BARE clause is only allowed on combined TARGET TEAMS + !$omp target ompx_bare + !$omp end target +end + +subroutine test2 + !$omp target +!ERROR: OMPX_BARE clause is only allowed on combined TARGET TEAMS + !$omp teams ompx_bare + !$omp end teams + !$omp end target +end + +subroutine test3 + integer i +!ERROR: OMPX_BARE clause is only allowed on combined TARGET TEAMS + !$omp target teams distribute ompx_bare + do i = 0, 10 + end do + !$omp end target teams distribute +end + +subroutine test4 +!No errors + !$omp target teams ompx_bare + !$omp end target teams +end diff --git a/flang/test/Semantics/OpenMP/reduction04.f90 b/flang/test/Semantics/OpenMP/reduction04.f90 index 319ed9f245abe..e86b67b6efa96 100644 --- a/flang/test/Semantics/OpenMP/reduction04.f90 +++ b/flang/test/Semantics/OpenMP/reduction04.f90 @@ -14,8 +14,7 @@ program omp_Reduction end do !$omp end parallel do - !ERROR: Variable 'c' on the REDUCTION clause is not definable - !BECAUSE: 'c' is not a variable + !ERROR: Common block names are not allowed in REDUCTION clause !$omp parallel do reduction(*:/c/) do i = 1, 10 l = k + 1 diff --git a/flang/test/Semantics/OpenMP/reduction06.f90 b/flang/test/Semantics/OpenMP/reduction06.f90 index 58290c61cae86..66aa9fc62c1bf 100644 --- a/flang/test/Semantics/OpenMP/reduction06.f90 +++ b/flang/test/Semantics/OpenMP/reduction06.f90 @@ -8,21 +8,21 @@ program omp_reduction integer :: k = 10 integer :: a(10), b(10,10,10) - !ERROR: A list item that appears in a REDUCTION clause should have a contiguous storage array section. + !ERROR: Reference to 'a' must be a contiguous object !$omp parallel do reduction(+:a(1:10:3)) do i = 1, 10 k = k + 1 end do !$omp end parallel do - !ERROR: A list item that appears in a REDUCTION clause should have a contiguous storage array section. + !ERROR: Reference to 'b' must be a contiguous object !$omp parallel do reduction(+:b(1:10:3,1:8:1,1:5:1)) do i = 1, 10 k = k + 1 end do !$omp end parallel do - !ERROR: A list item that appears in a REDUCTION clause should have a contiguous storage array section. + !ERROR: Reference to 'b' must be a contiguous object !$omp parallel do reduction(+:b(1:10:1,1:8:2,1:5:1)) do i = 1, 10 k = k + 1 diff --git a/flang/test/Semantics/OpenMP/reduction12.f90 b/flang/test/Semantics/OpenMP/reduction12.f90 index f896ca4aa60b6..f7e3baf046562 100644 --- a/flang/test/Semantics/OpenMP/reduction12.f90 +++ b/flang/test/Semantics/OpenMP/reduction12.f90 @@ -6,7 +6,7 @@ procedure(foo), pointer :: ptr integer :: i ptr => foo -!ERROR: A procedure pointer 'ptr' must not appear in a REDUCTION clause. +!ERROR: Procedure pointer 'ptr' may not appear in a REDUCTION clause !$omp do reduction (+ : ptr) do i = 1, 10 end do diff --git a/flang/test/Semantics/OpenMP/reduction15.f90 b/flang/test/Semantics/OpenMP/reduction15.f90 new file mode 100644 index 0000000000000..1d4de6ff702bb --- /dev/null +++ b/flang/test/Semantics/OpenMP/reduction15.f90 @@ -0,0 +1,32 @@ +!RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -fopenmp-version=50 + +!Ref: [5.0:297:28-29] +! If a list item is an array section or an array element, its base expression +! must be a base language identifier. + +module m + type t + integer :: a(10) + end type + +contains + + subroutine f00 + type(t) :: x + !ERROR: The base expression of an array element or section in REDUCTION clause must be an identifier + !$omp do reduction (+ : x%a(2)) + do i = 1, 10 + end do + !$omp end do + end subroutine + + subroutine f01 + type(t) :: x + !ERROR: The base expression of an array element or section in REDUCTION clause must be an identifier + !$omp do reduction (+ : x%a(1:10)) + do i = 1, 10 + end do + !$omp end do + end subroutine +end + diff --git a/flang/test/Semantics/OpenMP/reduction16.f90 b/flang/test/Semantics/OpenMP/reduction16.f90 new file mode 100644 index 0000000000000..6bb218e306128 --- /dev/null +++ b/flang/test/Semantics/OpenMP/reduction16.f90 @@ -0,0 +1,14 @@ +!RUN: %python %S/../test_errors.py %s %flang_fc1 -fopenmp -fopenmp-version=50 + +!Ref: [5.0:298:19] +! A type parameter inquiry cannot appear in a reduction clause. + +subroutine f00 + integer :: x +!ERROR: Type parameter inquiry is not permitted in REDUCTION clause +!$omp do reduction (+ : x%kind) + do i = 1, 10 + end do +!$omp end do +end subroutine + diff --git a/flang/test/Semantics/OpenMP/symbol08.f90 b/flang/test/Semantics/OpenMP/symbol08.f90 index 69ccd17391b54..80ae1c6d2242b 100644 --- a/flang/test/Semantics/OpenMP/symbol08.f90 +++ b/flang/test/Semantics/OpenMP/symbol08.f90 @@ -130,13 +130,14 @@ subroutine dotprod (b, c, n, block_size, num_teams, block_threads) !REF: /dotprod/sum sum = 0.0e0 !$omp target map(to:b,c) map(tofrom:sum) -!$omp teams num_teams(num_teams) thread_limit(block_threads) reduction(+:sum) +!$omp teams num_teams(num_teams) thread_limit(block_threads) reduction(+: sum& +!$OMP&) !$omp distribute !DEF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/i0 (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) !REF: /dotprod/n !REF: /dotprod/block_size do i0=1,n,block_size -!$omp parallel do reduction(+:sum) +!$omp parallel do reduction(+: sum) !DEF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/OtherConstruct1/i (OmpPrivate, OmpPreDetermined) HostAssoc INTEGER(4) !DEF: /dotprod/OtherConstruct1/OtherConstruct1/OtherConstruct1/OtherConstruct1/i0 HostAssoc INTEGER(4) !DEF: /dotprod/min ELEMENTAL, INTRINSIC, PURE (Function) ProcEntity diff --git a/flang/test/Semantics/OpenMP/task-reduction.f90 b/flang/test/Semantics/OpenMP/task-reduction.f90 new file mode 100644 index 0000000000000..5a18ee48e7728 --- /dev/null +++ b/flang/test/Semantics/OpenMP/task-reduction.f90 @@ -0,0 +1,70 @@ +!RUN: %python %S/../test_errors.py %s %flang -fopenmp -fopenmp-version=50 + +subroutine f00 + real :: x +!ERROR: The type of 'x' is incompatible with the reduction operator. +!$omp taskgroup task_reduction(.or.: x) +!$omp end taskgroup +end + +subroutine f01 + real :: x +!ERROR: Invalid reduction operator in TASK_REDUCTION clause. +!$omp taskgroup task_reduction(.not.: x) +!$omp end taskgroup +end + +subroutine f02(p) + integer, pointer, intent(in) :: p +!ERROR: Pointer 'p' with the INTENT(IN) attribute may not appear in a TASK_REDUCTION clause +!$omp taskgroup task_reduction(+: p) +!$omp end taskgroup +end + +subroutine f03 + common /c/ a, b +!ERROR: Common block names are not allowed in TASK_REDUCTION clause +!$omp taskgroup task_reduction(+: /c/) +!$omp end taskgroup +end + +subroutine f04 + integer :: x(10) +!ERROR: Reference to 'x' must be a contiguous object +!$omp taskgroup task_reduction(+: x(1:10:2)) +!$omp end taskgroup +end + +subroutine f05 + integer :: x(10) +!ERROR: 'x' in TASK_REDUCTION clause is a zero size array section +!$omp taskgroup task_reduction(+: x(1:0)) +!$omp end taskgroup +end + +subroutine f06 + type t + integer :: a(10) + end type + type(t) :: x +!ERROR: The base expression of an array element or section in TASK_REDUCTION clause must be an identifier +!$omp taskgroup task_reduction(+: x%a(2)) +!$omp end taskgroup +end + +subroutine f07 + type t + integer :: a(10) + end type + type(t) :: x +!ERROR: The base expression of an array element or section in TASK_REDUCTION clause must be an identifier +!$omp taskgroup task_reduction(+: x%a(1:10)) +!$omp end taskgroup +end + +subroutine f08 + integer :: x +!ERROR: Type parameter inquiry is not permitted in TASK_REDUCTION clause +!$omp taskgroup task_reduction(+: x%kind) +!$omp end taskgroup +end diff --git a/flang/test/Semantics/OpenMP/taskgroup01.f90 b/flang/test/Semantics/OpenMP/taskgroup01.f90 index e05051387411a..ded5d47525af4 100644 --- a/flang/test/Semantics/OpenMP/taskgroup01.f90 +++ b/flang/test/Semantics/OpenMP/taskgroup01.f90 @@ -41,6 +41,8 @@ !$omp task !$omp taskgroup task_reduction(+ : reduction_var) print *, "The " + !ERROR: The type of 'reduction_var' is incompatible with the reduction operator. + !ERROR: The type of 'reduction_var' is incompatible with the reduction operator. !$omp taskgroup task_reduction(.or. : reduction_var) task_reduction(.and. : reduction_var) print *, "almighty sun" !$omp end taskgroup diff --git a/flang/test/Semantics/OpenMP/to-clause-v45.f90 b/flang/test/Semantics/OpenMP/to-clause-v45.f90 index e4d8967ca14df..9797c06cdeddf 100644 --- a/flang/test/Semantics/OpenMP/to-clause-v45.f90 +++ b/flang/test/Semantics/OpenMP/to-clause-v45.f90 @@ -2,7 +2,7 @@ subroutine f00(x) integer :: x(10) -!ERROR: Reference to x must be a contiguous object +!ERROR: Reference to 'x' must be a contiguous object !$omp target update to(x(1:10:2)) end diff --git a/flang/test/Semantics/OpenMP/use_device_addr1.f90 b/flang/test/Semantics/OpenMP/use_device_addr1.f90 index e6a3e6e5b2a2d..350d236e00598 100644 --- a/flang/test/Semantics/OpenMP/use_device_addr1.f90 +++ b/flang/test/Semantics/OpenMP/use_device_addr1.f90 @@ -15,7 +15,7 @@ subroutine omp_target_data type(my_type) :: my_var a = 1 - !ERROR: A variable that is part of another variable (structure element) cannot appear on the TARGET DATA USE_DEVICE_ADDR clause + !ERROR: A variable that is part of another variable cannot appear on the USE_DEVICE_ADDR clause !$omp target data map(tofrom: a) use_device_addr(my_var%my_b) my_var%my_b = a !$omp end target data diff --git a/flang/test/Semantics/OpenMP/use_device_ptr1.f90 b/flang/test/Semantics/OpenMP/use_device_ptr1.f90 index 41dbadc59ce7c..5a5437e618450 100644 --- a/flang/test/Semantics/OpenMP/use_device_ptr1.f90 +++ b/flang/test/Semantics/OpenMP/use_device_ptr1.f90 @@ -20,7 +20,7 @@ subroutine omp_target_data type(my_type) :: my_var a = 1 - !ERROR: A variable that is part of another variable (structure element) cannot appear on the TARGET DATA USE_DEVICE_PTR clause + !ERROR: A variable that is part of another variable cannot appear on the USE_DEVICE_PTR clause !$omp target data map(tofrom: a, arrayB) use_device_ptr(my_var%my_cptr) allocate(arrayB) call c_f_pointer(my_var%my_cptr, arrayB) diff --git a/flang/test/Semantics/cuf09.cuf b/flang/test/Semantics/cuf09.cuf index 195ddac11d575..c551ecbff2cc0 100644 --- a/flang/test/Semantics/cuf09.cuf +++ b/flang/test/Semantics/cuf09.cuf @@ -1,5 +1,6 @@ ! RUN: %python %S/test_errors.py %s %flang_fc1 module m + integer :: m(100) contains attributes(device) subroutine devsub !ERROR: Statement may not appear in device code @@ -15,6 +16,12 @@ module m !WARNING: I/O statement might not be supported on device write(12,'(10F4.1)'), x end + attributes(global) subroutine hostglobal(a) + integer :: a(*) + i = threadIdx%x + !ERROR: Host array 'm' cannot be present in device context + if (i .le. N) a(i) = m(i) + end subroutine end program main @@ -96,7 +103,7 @@ program main !$cuf kernel do (2) <<<*, *>>> do j = 1, 10 do i = 1, 10 - !ERROR: Host array 'b' cannot be present in CUF kernel + !ERROR: Host array 'b' cannot be present in device context a_d(i,j) = b(i,j) enddo enddo diff --git a/flang/test/Semantics/modfile55.cuf b/flang/test/Semantics/modfile55.cuf index cf01bdd5f58f6..2338b745d8355 100644 --- a/flang/test/Semantics/modfile55.cuf +++ b/flang/test/Semantics/modfile55.cuf @@ -14,6 +14,10 @@ module m attributes(host,device) real function foo(x) foo = x + 1. end function + attributes(host) subroutine hostsub(a) + integer, intent(out) :: a(14) + a = 99 + end subroutine end !Expect: m.mod @@ -38,4 +42,7 @@ end !real(4)::x !real(4)::foo !end +attributes(host)subroutinehostsub(a) +integer(4),intent(out)::a(1_8:14_8) +end !end diff --git a/flang/test/Semantics/test_symbols.py b/flang/test/Semantics/test_symbols.py index 24dc5004a4229..612ae0df94e23 100755 --- a/flang/test/Semantics/test_symbols.py +++ b/flang/test/Semantics/test_symbols.py @@ -29,7 +29,7 @@ # Strips out blank lines and all comments except for "!DEF:", "!REF:", "!$acc" and "!$omp" with open(src, "r") as text_in: for line in text_in: - text = re.sub(r"!(?![DR]EF:|\$omp|\$acc).*", "", line) + text = re.sub(r"!(?![DR]EF:|\$omp|\$acc).*", "", line, flags=re.I) text = re.sub(r"^\s*$", "", text) diff1 += text diff --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp index 9f7d41b2c2276..b433ca8c2fb4d 100644 --- a/flang/tools/bbc/bbc.cpp +++ b/flang/tools/bbc/bbc.cpp @@ -240,12 +240,6 @@ static llvm::cl::opt integerWrapAround( llvm::cl::desc("Treat signed integer overflow as two's complement"), llvm::cl::init(false)); -// TODO: integrate this option with the above -static llvm::cl::opt - setNSW("integer-overflow", - llvm::cl::desc("add nsw flag to internal operations"), - llvm::cl::init(false)); - #define FLANG_EXCLUDE_CODEGEN #include "flang/Optimizer/Passes/CommandLineOpts.h" #include "flang/Optimizer/Passes/Pipelines.h" @@ -399,7 +393,6 @@ static llvm::LogicalResult convertFortranSourceToMLIR( loweringOptions.setNoPPCNativeVecElemOrder(enableNoPPCNativeVecElemOrder); loweringOptions.setLowerToHighLevelFIR(useHLFIR || emitHLFIR); loweringOptions.setIntegerWrapAround(integerWrapAround); - loweringOptions.setNSWOnLoopVarInc(setNSW); std::vector envDefaults = {}; Fortran::frontend::TargetOptions targetOpts; Fortran::frontend::CodeGenOptions cgOpts; @@ -488,7 +481,7 @@ static llvm::LogicalResult convertFortranSourceToMLIR( MLIRToLLVMPassPipelineConfig config(llvm::OptimizationLevel::O2); if (enableOpenMP) config.EnableOpenMP = true; - config.NSWOnLoopVarInc = setNSW; + config.NSWOnLoopVarInc = !integerWrapAround; fir::registerDefaultInlinerPass(config); fir::createDefaultFIROptimizerPassPipeline(pm, config); } diff --git a/flang/unittests/Optimizer/Builder/Runtime/AllocatableTest.cpp b/flang/unittests/Optimizer/Builder/Runtime/AllocatableTest.cpp index 1db43cacc90f0..f618e72d7b7f3 100644 --- a/flang/unittests/Optimizer/Builder/Runtime/AllocatableTest.cpp +++ b/flang/unittests/Optimizer/Builder/Runtime/AllocatableTest.cpp @@ -9,7 +9,7 @@ #include "flang/Optimizer/Builder/Runtime/Allocatable.h" #include "RuntimeCallTestBase.h" #include "gtest/gtest.h" -#include "flang/Runtime/descriptor.h" +#include "flang/Runtime/descriptor-consts.h" using namespace Fortran::runtime; diff --git a/flang/unittests/Runtime/AccessTest.cpp b/flang/unittests/Runtime/AccessTest.cpp index 66f19f78c7cfb..c2a2d7d398220 100644 --- a/flang/unittests/Runtime/AccessTest.cpp +++ b/flang/unittests/Runtime/AccessTest.cpp @@ -32,6 +32,12 @@ struct AccessType { } // namespace +static bool userSkipsPermissionChecks() { + // The tests in this file assume normal permission checks apply to the user + // running the tests. This isn't true when the test is run by root. + return geteuid() == 0; +} + static std::string addPIDSuffix(const char *name) { std::stringstream ss; ss << name; @@ -166,6 +172,10 @@ TEST(AccessTests, TestRead) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_EQ(res, 0); } @@ -181,6 +191,10 @@ TEST(AccessTests, TestNotRead) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_NE(res, 0); } @@ -195,6 +209,10 @@ TEST(AccessTests, TestWrite) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_EQ(res, 0); } @@ -210,6 +228,10 @@ TEST(AccessTests, TestNotWrite) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_NE(res, 0); } @@ -225,6 +247,10 @@ TEST(AccessTests, TestReadWrite) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_EQ(res, 0); } @@ -242,6 +268,10 @@ TEST(AccessTests, TestNotReadWrite0) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_NE(res, 0); } @@ -259,6 +289,10 @@ TEST(AccessTests, TestNotReadWrite1) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_NE(res, 0); } @@ -276,6 +310,10 @@ TEST(AccessTests, TestNotReadWrite2) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_NE(res, 0); } @@ -290,6 +328,10 @@ TEST(AccessTests, TestExecute) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_EQ(res, 0); } @@ -305,6 +347,10 @@ TEST(AccessTests, TestNotExecute) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_NE(res, 0); } @@ -321,6 +367,10 @@ TEST(AccessTests, TestRWX) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_EQ(res, 0); } @@ -340,6 +390,10 @@ TEST(AccessTests, TestNotRWX0) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_NE(res, 0); } @@ -359,6 +413,10 @@ TEST(AccessTests, TestNotRWX1) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_NE(res, 0); } @@ -378,6 +436,10 @@ TEST(AccessTests, TestNotRWX2) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_NE(res, 0); } @@ -397,6 +459,10 @@ TEST(AccessTests, TestNotRWX3) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_NE(res, 0); } @@ -416,6 +482,10 @@ TEST(AccessTests, TestNotRWX4) { ASSERT_EQ(unlink(path.c_str()), 0); + if (userSkipsPermissionChecks()) { + return; + } + ASSERT_NE(res, 0); } diff --git a/flang/unittests/Runtime/ArrayConstructor.cpp b/flang/unittests/Runtime/ArrayConstructor.cpp index 9d78da7962361..62e3b780a27e7 100644 --- a/flang/unittests/Runtime/ArrayConstructor.cpp +++ b/flang/unittests/Runtime/ArrayConstructor.cpp @@ -43,8 +43,7 @@ TEST(ArrayConstructor, Basic) { result.GetDimension(0).SetBounds(1, 0); RTNAME(InitArrayConstructorVector) - (*acVector, result, /*useValueLengthParameters=*/false, - /*vectorClassSize=*/sizeof(ArrayConstructorVector)); + (*acVector, result, /*useValueLengthParameters=*/false); for (std::int32_t i{0}; i <= 99; ++i) { RTNAME(PushArrayConstructorSimpleScalar)(*acVector, &i); RTNAME(PushArrayConstructorValue)(*acVector, *x); @@ -71,8 +70,7 @@ TEST(ArrayConstructor, Basic) { // and is allocated when the first value is pushed. result.GetDimension(0).SetBounds(1, 1234); RTNAME(InitArrayConstructorVector) - (*acVector, result, /*useValueLengthParameters=*/false, - /*vectorClassSize=*/sizeof(ArrayConstructorVector)); + (*acVector, result, /*useValueLengthParameters=*/false); EXPECT_EQ(0, acVector->actualAllocationSize); std::int32_t i{42}; RTNAME(PushArrayConstructorSimpleScalar)(*acVector, &i); @@ -109,8 +107,7 @@ TEST(ArrayConstructor, Character) { static constexpr std::size_t expectedElements{10 * (1 + 4 + 2 * 3)}; result.GetDimension(0).SetBounds(1, 0); RTNAME(InitArrayConstructorVector) - (*acVector, result, /*useValueLengthParameters=*/true, - /*vectorClassSize=*/sizeof(ArrayConstructorVector)); + (*acVector, result, /*useValueLengthParameters=*/true); for (std::int32_t i{1}; i <= 10; ++i) { RTNAME(PushArrayConstructorValue)(*acVector, *c); RTNAME(PushArrayConstructorValue)(*acVector, *x); @@ -151,8 +148,7 @@ TEST(ArrayConstructor, CharacterRuntimeCheck) { result.GetDimension(0).SetBounds(1, 0); RTNAME(InitArrayConstructorVector) - (*acVector, result, /*useValueLengthParameters=*/true, - /*vectorClassSize=*/sizeof(ArrayConstructorVector)); + (*acVector, result, /*useValueLengthParameters=*/true); RTNAME(PushArrayConstructorValue)(*acVector, *c2); ASSERT_DEATH(RTNAME(PushArrayConstructorValue)(*acVector, *c3), "Array constructor: mismatched character lengths"); diff --git a/flang/unittests/Runtime/CUDA/Allocatable.cpp b/flang/unittests/Runtime/CUDA/Allocatable.cpp index 171ca982a04f1..0f7eb27789316 100644 --- a/flang/unittests/Runtime/CUDA/Allocatable.cpp +++ b/flang/unittests/Runtime/CUDA/Allocatable.cpp @@ -42,8 +42,7 @@ TEST(AllocatableCUFTest, SimpleDeviceAllocatable) { CUDA_REPORT_IF_ERROR(cudaMalloc(&device_desc, a->SizeInBytes())); RTNAME(AllocatableAllocate) - (*a, /*asyncId=*/-1, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, - __LINE__); + (*a, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__); EXPECT_TRUE(a->IsAllocated()); RTNAME(CUFDescriptorSync)(device_desc, a.get(), __FILE__, __LINE__); cudaDeviceSynchronize(); diff --git a/flang/unittests/Runtime/CUDA/AllocatorCUF.cpp b/flang/unittests/Runtime/CUDA/AllocatorCUF.cpp index 435172890472d..b51ff0ac006cc 100644 --- a/flang/unittests/Runtime/CUDA/AllocatorCUF.cpp +++ b/flang/unittests/Runtime/CUDA/AllocatorCUF.cpp @@ -35,8 +35,7 @@ TEST(AllocatableCUFTest, SimpleDeviceAllocate) { EXPECT_FALSE(a->HasAddendum()); RTNAME(AllocatableSetBounds)(*a, 0, 1, 10); RTNAME(AllocatableAllocate) - (*a, /*asyncId=*/-1, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, - __LINE__); + (*a, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__); EXPECT_TRUE(a->IsAllocated()); RTNAME(AllocatableDeallocate) (*a, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__); @@ -54,8 +53,7 @@ TEST(AllocatableCUFTest, SimplePinnedAllocate) { EXPECT_FALSE(a->HasAddendum()); RTNAME(AllocatableSetBounds)(*a, 0, 1, 10); RTNAME(AllocatableAllocate) - (*a, /*asyncId=*/-1, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, - __LINE__); + (*a, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__); EXPECT_TRUE(a->IsAllocated()); RTNAME(AllocatableDeallocate) (*a, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__); diff --git a/flang/unittests/Runtime/CUDA/Memory.cpp b/flang/unittests/Runtime/CUDA/Memory.cpp index 2f40915af3867..7c8b7aa5a4d78 100644 --- a/flang/unittests/Runtime/CUDA/Memory.cpp +++ b/flang/unittests/Runtime/CUDA/Memory.cpp @@ -51,8 +51,7 @@ TEST(MemoryCUFTest, CUFDataTransferDescDesc) { EXPECT_EQ((int)kDeviceAllocatorPos, dev->GetAllocIdx()); RTNAME(AllocatableSetBounds)(*dev, 0, 1, 10); RTNAME(AllocatableAllocate) - (*dev, /*asyncId=*/-1, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, - __LINE__); + (*dev, /*hasStat=*/false, /*errMsg=*/nullptr, __FILE__, __LINE__); EXPECT_TRUE(dev->IsAllocated()); // Create temp array to transfer to device. diff --git a/flang/unittests/Runtime/ExternalIOTest.cpp b/flang/unittests/Runtime/ExternalIOTest.cpp index 13327964e12a4..b9407b5e7a591 100644 --- a/flang/unittests/Runtime/ExternalIOTest.cpp +++ b/flang/unittests/Runtime/ExternalIOTest.cpp @@ -13,7 +13,7 @@ #include "CrashHandlerFixture.h" #include "gtest/gtest.h" #include "flang/Runtime/descriptor.h" -#include "flang/Runtime/io-api.h" +#include "flang/Runtime/io-api-consts.h" #include "flang/Runtime/main.h" #include "flang/Runtime/stop.h" #include "llvm/Support/raw_ostream.h" diff --git a/flang/unittests/Runtime/ListInputTest.cpp b/flang/unittests/Runtime/ListInputTest.cpp index a4eba5283add6..38c758b7ef966 100644 --- a/flang/unittests/Runtime/ListInputTest.cpp +++ b/flang/unittests/Runtime/ListInputTest.cpp @@ -9,7 +9,7 @@ #include "CrashHandlerFixture.h" #include "../../runtime/io-error.h" #include "flang/Runtime/descriptor.h" -#include "flang/Runtime/io-api.h" +#include "flang/Runtime/io-api-consts.h" using namespace Fortran::runtime; using namespace Fortran::runtime::io; diff --git a/flang/unittests/Runtime/LogicalFormatTest.cpp b/flang/unittests/Runtime/LogicalFormatTest.cpp index a2c19d1e1ca94..c4fbfc81f06a4 100644 --- a/flang/unittests/Runtime/LogicalFormatTest.cpp +++ b/flang/unittests/Runtime/LogicalFormatTest.cpp @@ -8,7 +8,7 @@ #include "CrashHandlerFixture.h" #include "flang/Runtime/descriptor.h" -#include "flang/Runtime/io-api.h" +#include "flang/Runtime/io-api-consts.h" #include #include #include diff --git a/flang/unittests/Runtime/Namelist.cpp b/flang/unittests/Runtime/Namelist.cpp index 9037fa15a97cb..0a28f3590b86e 100644 --- a/flang/unittests/Runtime/Namelist.cpp +++ b/flang/unittests/Runtime/Namelist.cpp @@ -10,7 +10,7 @@ #include "CrashHandlerFixture.h" #include "tools.h" #include "flang/Runtime/descriptor.h" -#include "flang/Runtime/io-api.h" +#include "flang/Runtime/io-api-consts.h" #include #include #include diff --git a/flang/unittests/Runtime/NumericalFormatTest.cpp b/flang/unittests/Runtime/NumericalFormatTest.cpp index f005515320350..274498b8e8695 100644 --- a/flang/unittests/Runtime/NumericalFormatTest.cpp +++ b/flang/unittests/Runtime/NumericalFormatTest.cpp @@ -8,7 +8,7 @@ #include "CrashHandlerFixture.h" #include "flang/Runtime/descriptor.h" -#include "flang/Runtime/io-api.h" +#include "flang/Runtime/io-api-consts.h" #include #include #include diff --git a/flang/unittests/Runtime/RuntimeCrashTest.cpp b/flang/unittests/Runtime/RuntimeCrashTest.cpp index a649051fdca0c..72a0b290cf864 100644 --- a/flang/unittests/Runtime/RuntimeCrashTest.cpp +++ b/flang/unittests/Runtime/RuntimeCrashTest.cpp @@ -13,7 +13,7 @@ #include "CrashHandlerFixture.h" #include "tools.h" #include "../../runtime/terminator.h" -#include "flang/Runtime/io-api.h" +#include "flang/Runtime/io-api-consts.h" #include "flang/Runtime/transformational.h" #include diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt index 5196735bef4e7..88cc75e83b043 100644 --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -1,12 +1,19 @@ cmake_minimum_required(VERSION 3.20.0) 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.") +endif() + # Include LLVM's cmake policies. if(NOT DEFINED LLVM_COMMON_CMAKE_UTILS) set(LLVM_COMMON_CMAKE_UTILS ${CMAKE_CURRENT_SOURCE_DIR}/../cmake) endif() include(${LLVM_COMMON_CMAKE_UTILS}/Modules/CMakePolicy.cmake NO_POLICY_SCOPE) +include(CheckCXXCompilerFlag) if (LIBC_CMAKE_VERBOSE_LOGGING) get_directory_property(LIBC_OLD_PREPROCESSOR_DEFS COMPILE_DEFINITIONS) diff --git a/libc/benchmarks/CMakeLists.txt b/libc/benchmarks/CMakeLists.txt index 52e3f942d16ea..60f522d7d8c65 100644 --- a/libc/benchmarks/CMakeLists.txt +++ b/libc/benchmarks/CMakeLists.txt @@ -204,13 +204,11 @@ target_link_libraries(libc.benchmarks.memory_functions.opt_host PRIVATE libc-memory-benchmark libc.src.string.memcmp_opt_host.__internal__ - libc.src.string.bcmp_opt_host.__internal__ libc.src.string.memcpy_opt_host.__internal__ - libc.src.string.memset_opt_host.__internal__ - libc.src.string.bzero_opt_host.__internal__ libc.src.string.memmove_opt_host.__internal__ + libc.src.string.memset_opt_host.__internal__ + libc.src.strings.bcmp_opt_host.__internal__ + libc.src.strings.bzero_opt_host.__internal__ benchmark_main ) llvm_update_compile_flags(libc.benchmarks.memory_functions.opt_host) - -add_subdirectory(automemcpy) diff --git a/libc/benchmarks/automemcpy/CMakeLists.txt b/libc/benchmarks/automemcpy/CMakeLists.txt deleted file mode 100644 index ef9b4218c8d61..0000000000000 --- a/libc/benchmarks/automemcpy/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -if(NOT LIBC_BUILD_AUTOMEMCPY) - return () -endif() - -if(NOT LLVM_WITH_Z3) - MESSAGE(FATAL_ERROR "Building llvm-libc automemcpy requires Z3") -endif() - -set(LIBC_AUTOMEMCPY_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) - -add_subdirectory(lib) -add_subdirectory(unittests) diff --git a/libc/benchmarks/automemcpy/README.md b/libc/benchmarks/automemcpy/README.md deleted file mode 100644 index 8583368993ef0..0000000000000 --- a/libc/benchmarks/automemcpy/README.md +++ /dev/null @@ -1,111 +0,0 @@ -This folder contains an implementation of [automemcpy: A framework for automatic generation of fundamental memory operations](https://research.google/pubs/pub50338/). - -It uses the [Z3 theorem prover](https://github.com/Z3Prover/z3) to enumerate a subset of valid memory function implementations. These implementations are then materialized as C++ code and can be [benchmarked](../) against various [size distributions](../distributions). This process helps the design of efficient implementations for a particular environnement (size distribution, processor or custom compilation options). - -This is not enabled by default, as it is mostly useful when working on tuning the library implementation. To build it, use `LIBC_BUILD_AUTOMEMCPY=ON` (see below). - -## Prerequisites - -You may need to install `Z3` from source if it's not available on your system. -Here we show instructions to install it into ``. -You may need to `sudo` to `make install`. - -```shell -mkdir -p ~/git -cd ~/git -git clone https://github.com/Z3Prover/z3.git -python scripts/mk_make.py --prefix= -cd build -make -j -make install -``` - -## Configuration - -```shell -mkdir -p -cd /llvm -cmake -DCMAKE_C_COMPILER=/usr/bin/clang \ - -DCMAKE_CXX_COMPILER=/usr/bin/clang++ \ - -DLLVM_ENABLE_PROJECTS="libc" \ - -DLLVM_ENABLE_Z3_SOLVER=ON \ - -DLLVM_Z3_INSTALL_DIR= \ - -DLIBC_BUILD_AUTOMEMCPY=ON \ - -DCMAKE_BUILD_TYPE=Release \ - -B -``` - -## Targets and compilation - -There are three main CMake targets - 1. `automemcpy_implementations` - - runs `Z3` and materializes valid memory functions as C++ code, a message will display its ondisk location. - - the source code is then compiled using the native host optimizations (i.e. `-march=native` or `-mcpu=native` depending on the architecture). - 2. `automemcpy` - - the binary that benchmarks the autogenerated implementations. - 3. `automemcpy_result_analyzer` - - the binary that analyses the benchmark results. - -You may only compile the binaries as they both pull the autogenerated code as a dependency. - -```shell -make -C -j automemcpy automemcpy_result_analyzer -``` - -## Running the benchmarks - -Make sure to save the results of the benchmark as a json file. - -```shell -/bin/automemcpy --benchmark_out_format=json --benchmark_out=/results.json -``` - -### Additional useful options - - - - `--benchmark_min_time=.2` - - By default, each function is benchmarked for at least one second, here we lower it to 200ms. - - - `--benchmark_filter="BM_Memset|BM_Bzero"` - - By default, all functions are benchmarked, here we restrict them to `memset` and `bzero`. - -Other options might be useful, use `--help` for more information. - -## Analyzing the benchmarks - -Analysis is performed by running `automemcpy_result_analyzer` on one or more json result files. - -```shell -/bin/automemcpy_result_analyzer /results.json -``` - -What it does: - 1. Gathers all throughput values for each function / distribution pair and picks the median one.\ - This allows picking a representative value over many runs of the benchmark. Please make sure all the runs happen under similar circumstances. - - 2. For each distribution, look at the span of throughputs for functions of the same type (e.g. For distribution `A`, memcpy throughput spans from 2GiB/s to 5GiB/s). - - 3. For each distribution, give a normalized score to each function (e.g. For distribution `A`, function `M` scores 0.65).\ - This score is then turned into a grade `EXCELLENT`, `VERY_GOOD`, `GOOD`, `PASSABLE`, `INADEQUATE`, `MEDIOCRE`, `BAD` - so that each distribution categorizes how function perform according to them. - - 4. A [Majority Judgement](https://en.wikipedia.org/wiki/Majority_judgment) process is then used to categorize each function. This enables finer analysis of how distributions agree on which function is better. In the following example, `Function_1` and `Function_2` are rated `EXCELLENT` but looking at the grade's distribution might help decide which is best. - -| | EXCELLENT | VERY_GOOD | GOOD | PASSABLE | INADEQUATE | MEDIOCRE | BAD | -|------------|:---------:|:---------:|:----:|:--------:|:----------:|:--------:|:---:| -| Function_1 | 7 | 1 | 2 | | | | | -| Function_2 | 6 | 4 | | | | | | - -The tool outputs the histogram of grades for each function. In case of tie, other dimensions might help decide (e.g. code size, performance on other microarchitectures). - -``` -EXCELLENT |█▁▂ | Function_0 -EXCELLENT |█▅ | Function_1 -VERY_GOOD |▂█▁ ▁ | Function_2 -GOOD | ▁█▄ | Function_3 -PASSABLE | ▂▆▄█ | Function_4 -INADEQUATE | ▃▃█▁ | Function_5 -MEDIOCRE | █▆▁| Function_6 -BAD | ▁▁█| Function_7 -``` diff --git a/libc/benchmarks/automemcpy/include/automemcpy/CodeGen.h b/libc/benchmarks/automemcpy/include/automemcpy/CodeGen.h deleted file mode 100644 index 389e8249f9399..0000000000000 --- a/libc/benchmarks/automemcpy/include/automemcpy/CodeGen.h +++ /dev/null @@ -1,26 +0,0 @@ -//===-- C++ code generation from NamedFunctionDescriptors -------*- 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 LIBC_BENCHMARKS_AUTOMEMCPY_CODEGEN_H -#define LIBC_BENCHMARKS_AUTOMEMCPY_CODEGEN_H - -#include "automemcpy/FunctionDescriptor.h" -#include -#include -#include - -namespace llvm { -namespace automemcpy { - -// This function serializes the array of FunctionDescriptors as a C++ file. -void Serialize(raw_ostream &Stream, ArrayRef FD); - -} // namespace automemcpy -} // namespace llvm - -#endif // LIBC_BENCHMARKS_AUTOMEMCPY_CODEGEN_H diff --git a/libc/benchmarks/automemcpy/include/automemcpy/FunctionDescriptor.h b/libc/benchmarks/automemcpy/include/automemcpy/FunctionDescriptor.h deleted file mode 100644 index 65477d9d72a0e..0000000000000 --- a/libc/benchmarks/automemcpy/include/automemcpy/FunctionDescriptor.h +++ /dev/null @@ -1,159 +0,0 @@ -//===-- Pod structs to describe a memory 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_BENCHMARKS_AUTOMEMCPY_COMMON_H -#define LLVM_LIBC_BENCHMARKS_AUTOMEMCPY_COMMON_H - -#include -#include -#include -#include -#include -#include -#include - -namespace llvm { -namespace automemcpy { - -// Boilerplate code to be able to sort and hash types. -#define COMPARABLE_AND_HASHABLE(T, ...) \ - inline auto asTuple() const { return std::tie(__VA_ARGS__); } \ - bool operator==(const T &O) const { return asTuple() == O.asTuple(); } \ - bool operator<(const T &O) const { return asTuple() < O.asTuple(); } \ - struct Hasher { \ - std::size_t operator()(const T &K) const { \ - return llvm::hash_value(K.asTuple()); \ - } \ - }; - -// Represents the maximum value for the size parameter of a memory function. -// This is an `int` so we can use it as an expression in Z3. -// It also allows for a more readable and compact representation when storing -// the SizeSpan in the autogenerated C++ file. -static constexpr int kMaxSize = INT_MAX; - -// This mimics the `Arg` type in libc/src/string/memory_utils/elements.h without -// having to depend on it. -enum class AlignArg { _1, _2, ARRAY_SIZE }; - -// Describes a range of sizes. -// We use the begin/end representation instead of first/last to allow for empty -// range (i.e. Begin == End) -struct SizeSpan { - size_t Begin = 0; - size_t End = 0; - - COMPARABLE_AND_HASHABLE(SizeSpan, Begin, End) -}; - -// Describes a contiguous region. -// In such a region all sizes are handled individually. -// e.g. with Span = {0, 2}; -// if(size == 0) return Handle<0>(); -// if(size == 1) return Handle<1>(); -struct Contiguous { - SizeSpan Span; - - COMPARABLE_AND_HASHABLE(Contiguous, Span) -}; - -// This struct represents a range of sizes over which to use an overlapping -// strategy. An overlapping strategy of size N handles all sizes from N to 2xN. -// The span may represent several contiguous overlaps. -// e.g. with Span = {16, 128}; -// if(size >= 16 and size < 32) return Handle>(); -// if(size >= 32 and size < 64) return Handle>(); -// if(size >= 64 and size < 128) return Handle>(); -struct Overlap { - SizeSpan Span; - - COMPARABLE_AND_HASHABLE(Overlap, Span) -}; - -// Describes a region using a loop handling BlockSize bytes at a time. The -// remaining bytes of the loop are handled with an overlapping operation. -struct Loop { - SizeSpan Span; - size_t BlockSize = 0; - - COMPARABLE_AND_HASHABLE(Loop, Span, BlockSize) -}; - -// Same as `Loop` but starts by aligning a buffer on `Alignment` bytes. -// A first operation handling 'Alignment` bytes is performed followed by a -// sequence of Loop.BlockSize bytes operation. The Loop starts processing from -// the next aligned byte in the chosen buffer. The remaining bytes of the loop -// are handled with an overlapping operation. -struct AlignedLoop { - Loop Loop; - size_t Alignment = 0; // Size of the alignment. - AlignArg AlignTo = AlignArg::_1; // Which buffer to align. - - COMPARABLE_AND_HASHABLE(AlignedLoop, Loop, Alignment, AlignTo) -}; - -// Some processors offer special instruction to handle the memory function -// completely, we refer to such instructions as accelerators. -struct Accelerator { - SizeSpan Span; - - COMPARABLE_AND_HASHABLE(Accelerator, Span) -}; - -// The memory functions are assembled out of primitives that can be implemented -// with regular scalar operations (SCALAR), with the help of vector or bitcount -// instructions (NATIVE) or by deferring it to the compiler (BUILTIN). -enum class ElementTypeClass { - SCALAR, - NATIVE, - BUILTIN, -}; - -// A simple enum to categorize which function is being implemented. -enum class FunctionType { - MEMCPY, - MEMCMP, - BCMP, - MEMSET, - BZERO, -}; - -// This struct describes the skeleton of the implementation, it does not go into -// every detail but is enough to uniquely identify the implementation. -struct FunctionDescriptor { - FunctionType Type; - std::optional Contiguous; - std::optional Overlap; - std::optional Loop; - std::optional AlignedLoop; - std::optional Accelerator; - ElementTypeClass ElementClass; - - COMPARABLE_AND_HASHABLE(FunctionDescriptor, Type, Contiguous, Overlap, Loop, - AlignedLoop, Accelerator, ElementClass) - - inline size_t id() const { return llvm::hash_value(asTuple()); } -}; - -// Same as above but with the function name. -struct NamedFunctionDescriptor { - StringRef Name; - FunctionDescriptor Desc; -}; - -template llvm::hash_code hash_value(const ArrayRef &V) { - return llvm::hash_combine_range(V.begin(), V.end()); -} -template llvm::hash_code hash_value(const T &O) { - return llvm::hash_value(O.asTuple()); -} - -} // namespace automemcpy -} // namespace llvm - -#endif /* LLVM_LIBC_BENCHMARKS_AUTOMEMCPY_COMMON_H */ diff --git a/libc/benchmarks/automemcpy/include/automemcpy/RandomFunctionGenerator.h b/libc/benchmarks/automemcpy/include/automemcpy/RandomFunctionGenerator.h deleted file mode 100644 index 28756e8f86c0e..0000000000000 --- a/libc/benchmarks/automemcpy/include/automemcpy/RandomFunctionGenerator.h +++ /dev/null @@ -1,62 +0,0 @@ -//===-- Generate random but valid function descriptors ---------*- 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_BENCHMARKS_AUTOMEMCPY_RANDOM_FUNCTION_GENERATOR_H -#define LLVM_LIBC_BENCHMARKS_AUTOMEMCPY_RANDOM_FUNCTION_GENERATOR_H - -#include "automemcpy/FunctionDescriptor.h" -#include -#include -#include -#include -#include -#include -#include - -namespace llvm { -namespace automemcpy { - -// Holds the state for the constraint solver. -// It implements a single method that returns the next valid description. -struct RandomFunctionGenerator { - RandomFunctionGenerator(); - - // Get the next valid FunctionDescriptor or std::nullopt. - std::optional next(); - -private: - // Returns an expression where `Variable` is forced to be one of the `Values`. - z3::expr inSetConstraint(z3::expr &Variable, ArrayRef Values) const; - // Add constaints to `Begin` and `End` so that they are: - // - between 0 and kMaxSize (inclusive) - // - ordered (begin<=End) - // - amongst a set of predefined values. - void addBoundsAndAnchors(z3::expr &Begin, z3::expr &End); - // Add constraints to make sure that the loop block size is amongst a set of - // predefined values. Also makes sure that the loop that the loop is iterated - // at least `LoopMinIter` times. - void addLoopConstraints(const z3::expr &LoopBegin, const z3::expr &LoopEnd, - z3::expr &LoopBlockSize, int LoopMinIter); - - z3::context Context; - z3::solver Solver; - - z3::expr Type; - z3::expr ContiguousBegin, ContiguousEnd; - z3::expr OverlapBegin, OverlapEnd; - z3::expr LoopBegin, LoopEnd, LoopBlockSize; - z3::expr AlignedLoopBegin, AlignedLoopEnd, AlignedLoopBlockSize, - AlignedAlignment, AlignedArg; - z3::expr AcceleratorBegin, AcceleratorEnd; - z3::expr ElementClass; -}; - -} // namespace automemcpy -} // namespace llvm - -#endif /* LLVM_LIBC_BENCHMARKS_AUTOMEMCPY_RANDOM_FUNCTION_GENERATOR_H */ diff --git a/libc/benchmarks/automemcpy/include/automemcpy/ResultAnalyzer.h b/libc/benchmarks/automemcpy/include/automemcpy/ResultAnalyzer.h deleted file mode 100644 index d4bf272582767..0000000000000 --- a/libc/benchmarks/automemcpy/include/automemcpy/ResultAnalyzer.h +++ /dev/null @@ -1,109 +0,0 @@ -//===-- Analyze benchmark JSON files ----------------------------*- 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 LIBC_BENCHMARKS_AUTOMEMCPY_RESULTANALYZER_H -#define LIBC_BENCHMARKS_AUTOMEMCPY_RESULTANALYZER_H - -#include "automemcpy/FunctionDescriptor.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringMap.h" -#include -#include - -namespace llvm { -namespace automemcpy { - -// A Grade as in the Majority Judgment voting system. -struct Grade { - enum GradeEnum { - EXCELLENT, - VERY_GOOD, - GOOD, - PASSABLE, - INADEQUATE, - MEDIOCRE, - BAD, - ARRAY_SIZE, - }; - - // Returns a human readable string of the enum. - static StringRef getString(const GradeEnum &GE); - - // Turns 'Score' into a GradeEnum. - static GradeEnum judge(double Score); -}; - -// A 'GradeEnum' indexed array with counts for each grade. -using GradeHistogram = std::array; - -// Identifies a Function by its name and type. Used as a key in a map. -struct FunctionId { - StringRef Name; - FunctionType Type; - COMPARABLE_AND_HASHABLE(FunctionId, Type, Name) -}; - -struct PerDistributionData { - std::vector BytesPerSecondSamples; - double BytesPerSecondMedian; // Median of samples for this distribution. - double BytesPerSecondMean; // Mean of samples for this distribution. - double BytesPerSecondVariance; // Variance of samples for this distribution. - double Score; // Normalized score for this distribution. - Grade::GradeEnum Grade; // Grade for this distribution. -}; - -struct FunctionData { - FunctionId Id; - StringMap PerDistributionData; - double ScoresGeoMean; // Geomean of scores for each distribution. - GradeHistogram GradeHisto = {}; // GradeEnum indexed array - Grade::GradeEnum FinalGrade = Grade::BAD; // Overall grade for this function -}; - -// Identifies a Distribution by its name. Used as a key in a map. -struct DistributionId { - StringRef Name; - COMPARABLE_AND_HASHABLE(DistributionId, Name) -}; - -// Identifies a Sample by its distribution and function. Used as a key in a map. -struct SampleId { - FunctionId Function; - DistributionId Distribution; - COMPARABLE_AND_HASHABLE(SampleId, Function.Type, Function.Name, - Distribution.Name) -}; - -// The type of Samples as reported by the Google Benchmark's JSON result file. -// We are only interested in the "iteration" samples, the "aggregate" ones -// represent derived metrics such as 'mean' or 'median'. -enum class SampleType { UNKNOWN, ITERATION, AGGREGATE }; - -// A SampleId with an associated measured throughput. -struct Sample { - SampleId Id; - SampleType Type = SampleType::UNKNOWN; - double BytesPerSecond = 0; -}; - -// This function collects Samples that belong to the same distribution and -// function and retains the median one. It then stores each of them into a -// 'FunctionData' and returns them as a vector. -std::vector getThroughputs(ArrayRef Samples); - -// Normalize the function's throughput per distribution. -void fillScores(MutableArrayRef Functions); - -// Convert scores into Grades, stores an histogram of Grade for each functions -// and cast a median grade for the function. -void castVotes(MutableArrayRef Functions); - -} // namespace automemcpy -} // namespace llvm - -#endif // LIBC_BENCHMARKS_AUTOMEMCPY_RESULTANALYZER_H diff --git a/libc/benchmarks/automemcpy/lib/CMakeLists.txt b/libc/benchmarks/automemcpy/lib/CMakeLists.txt deleted file mode 100644 index e66b9045b6074..0000000000000 --- a/libc/benchmarks/automemcpy/lib/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -add_library(automemcpy_codegen CodeGen.cpp) -target_link_libraries(automemcpy_codegen PUBLIC LLVMSupport) -target_include_directories(automemcpy_codegen PUBLIC ${LIBC_AUTOMEMCPY_INCLUDE_DIR}) -llvm_update_compile_flags(automemcpy_codegen) - -add_executable(automemcpy_codegen_main CodeGenMain.cpp RandomFunctionGenerator.cpp) -target_link_libraries(automemcpy_codegen_main PUBLIC automemcpy_codegen ${Z3_LIBRARIES}) -llvm_update_compile_flags(automemcpy_codegen_main) - -set(Implementations "${CMAKE_CURRENT_BINARY_DIR}/Implementations.cpp") -add_custom_command( - OUTPUT ${Implementations} - COMMAND "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/automemcpy_codegen_main" > "${Implementations}" - COMMAND echo "automemcpy implementations generated in ${Implementations}" - WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" - DEPENDS automemcpy_codegen_main -) - -add_library(automemcpy_implementations "${Implementations}") -target_link_libraries(automemcpy_implementations PUBLIC LLVMSupport libc-memory-benchmark) -target_include_directories(automemcpy_implementations PRIVATE - ${LIBC_SOURCE_DIR} ${LIBC_AUTOMEMCPY_INCLUDE_DIR}) -target_compile_options(automemcpy_implementations PRIVATE ${LIBC_COMPILE_OPTIONS_NATIVE} "SHELL:-mllvm -combiner-global-alias-analysis" -fno-builtin) -llvm_update_compile_flags(automemcpy_implementations) - -add_executable(automemcpy EXCLUDE_FROM_ALL ${LIBC_SOURCE_DIR}/benchmarks/LibcMemoryGoogleBenchmarkMain.cpp) -target_link_libraries(automemcpy PRIVATE libc-memory-benchmark benchmark_main automemcpy_implementations) -llvm_update_compile_flags(automemcpy) - -add_library(automemcpy_result_analyzer_lib EXCLUDE_FROM_ALL ResultAnalyzer.cpp) -target_link_libraries(automemcpy_result_analyzer_lib PUBLIC LLVMSupport) -target_include_directories(automemcpy_result_analyzer_lib PUBLIC ${LIBC_AUTOMEMCPY_INCLUDE_DIR}) -llvm_update_compile_flags(automemcpy_result_analyzer_lib) - -add_executable(automemcpy_result_analyzer EXCLUDE_FROM_ALL ResultAnalyzerMain.cpp) -target_link_libraries(automemcpy_result_analyzer PRIVATE automemcpy_result_analyzer_lib automemcpy_implementations) -llvm_update_compile_flags(automemcpy_result_analyzer) diff --git a/libc/benchmarks/automemcpy/lib/CodeGen.cpp b/libc/benchmarks/automemcpy/lib/CodeGen.cpp deleted file mode 100644 index d1336eaf31f34..0000000000000 --- a/libc/benchmarks/automemcpy/lib/CodeGen.cpp +++ /dev/null @@ -1,644 +0,0 @@ -//===-- C++ code generation from NamedFunctionDescriptors -----------------===// -// -// 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 code is responsible for generating the "Implementation.cpp" file. -// The file is composed like this: -// -// 1. Includes -// 2. Using statements to help readability. -// 3. Source code for all the mem function implementations. -// 4. The function to retrieve all the function descriptors with their name. -// llvm::ArrayRef getFunctionDescriptors(); -// 5. The functions for the benchmarking infrastructure: -// llvm::ArrayRef getMemcpyConfigurations(); -// llvm::ArrayRef getMemcmpConfigurations(); -// llvm::ArrayRef getBcmpConfigurations(); -// llvm::ArrayRef getMemsetConfigurations(); -// llvm::ArrayRef getBzeroConfigurations(); -// -// -// Sections 3, 4 and 5 are handled by the following namespaces: -// - codegen::functions -// - codegen::descriptors -// - codegen::configurations -// -// The programming style is functionnal. In each of these namespace, the -// original `NamedFunctionDescriptor` object is turned into a different type. We -// make use of overloaded stream operators to format the resulting type into -// either a function, a descriptor or a configuration. The entry point of each -// namespace is the Serialize function. -// -// Note the code here is better understood by starting from the `Serialize` -// function at the end of the file. - -#include "automemcpy/CodeGen.h" -#include "src/__support/macros/config.h" -#include -#include -#include -#include -#include -#include -#include - -namespace llvm { -namespace automemcpy { -namespace codegen { - -// The indentation string. -static constexpr StringRef kIndent = " "; - -// The codegen namespace handles the serialization of a NamedFunctionDescriptor -// into source code for the function, the descriptor and the configuration. - -namespace functions { - -// This namespace turns a NamedFunctionDescriptor into an actual implementation. -// ----------------------------------------------------------------------------- -// e.g. -// static void memcpy_0xB20D4702493C397E(char *__restrict dst, -// const char *__restrict src, -// size_t size) { -// using namespace LIBC_NAMESPACE::x86; -// if(size == 0) return; -// if(size == 1) return copy<_1>(dst, src); -// if(size < 4) return copy>(dst, src, size); -// if(size < 8) return copy>(dst, src, size); -// if(size < 16) return copy>(dst, src, size); -// if(size < 32) return copy>(dst, src, size); -// return copy(dst, src, size); -// } - -// The `Serialize` method turns a `NamedFunctionDescriptor` into a -// `FunctionImplementation` which holds all the information needed to produce -// the C++ source code. - -// An Element with its size (e.g. `_16` in the example above). -struct ElementType { - size_t Size; -}; -// The case `if(size == 0)` is encoded as a the Zero type. -struct Zero { - StringRef DefaultReturnValue; -}; -// An individual size `if(size == X)` is encoded as an Individual type. -struct Individual { - size_t IfEq; - ElementType Element; -}; -// An overlap strategy is encoded as an Overlap type. -struct Overlap { - size_t IfLt; - ElementType Element; -}; -// A loop strategy is encoded as a Loop type. -struct Loop { - size_t IfLt; - ElementType Element; -}; -// An aligned loop strategy is encoded as an AlignedLoop type. -struct AlignedLoop { - size_t IfLt; - ElementType Element; - ElementType Alignment; - StringRef AlignTo; -}; -// The accelerator strategy. -struct Accelerator { - size_t IfLt; -}; -// The Context stores data about the function type. -struct Context { - StringRef FunctionReturnType; // e.g. void* or int - StringRef FunctionArgs; - StringRef ElementOp; // copy, three_way_compare, splat_set, ... - StringRef FixedSizeArgs; - StringRef RuntimeSizeArgs; - StringRef DefaultReturnValue; -}; -// A detailed representation of the function implementation mapped from the -// NamedFunctionDescriptor. -struct FunctionImplementation { - Context Ctx; - StringRef Name; - std::vector Individuals; - std::vector Overlaps; - std::optional Loop; - std::optional AlignedLoop; - std::optional Accelerator; - ElementTypeClass ElementClass; -}; - -// Returns the Context for each FunctionType. -static Context getCtx(FunctionType FT) { - switch (FT) { - case FunctionType::MEMCPY: - return {"void", - "(char *__restrict dst, const char *__restrict src, size_t size)", - "copy", - "(dst, src)", - "(dst, src, size)", - ""}; - case FunctionType::MEMCMP: - return {"int", - "(const char * lhs, const char * rhs, size_t size)", - "three_way_compare", - "(lhs, rhs)", - "(lhs, rhs, size)", - "0"}; - case FunctionType::MEMSET: - return {"void", - "(char * dst, int value, size_t size)", - "splat_set", - "(dst, value)", - "(dst, value, size)", - ""}; - case FunctionType::BZERO: - return {"void", "(char * dst, size_t size)", - "splat_set", "(dst, 0)", - "(dst, 0, size)", ""}; - default: - report_fatal_error("Not yet implemented"); - } -} - -static StringRef getAligntoString(const AlignArg &AlignTo) { - switch (AlignTo) { - case AlignArg::_1: - return "Arg::P1"; - case AlignArg::_2: - return "Arg::P2"; - case AlignArg::ARRAY_SIZE: - report_fatal_error("logic error"); - } -} - -static raw_ostream &operator<<(raw_ostream &Stream, const ElementType &E) { - return Stream << '_' << E.Size; -} -static raw_ostream &operator<<(raw_ostream &Stream, const Individual &O) { - return Stream << O.Element; -} -static raw_ostream &operator<<(raw_ostream &Stream, const Overlap &O) { - return Stream << "HeadTail<" << O.Element << '>'; -} -static raw_ostream &operator<<(raw_ostream &Stream, const Loop &O) { - return Stream << "Loop<" << O.Element << '>'; -} -static raw_ostream &operator<<(raw_ostream &Stream, const AlignedLoop &O) { - return Stream << "Align<" << O.Alignment << ',' << O.AlignTo << ">::Then<" - << Loop{O.IfLt, O.Element} << ">"; -} -static raw_ostream &operator<<(raw_ostream &Stream, const Accelerator &O) { - return Stream << "Accelerator"; -} - -template struct IfEq { - StringRef Op; - StringRef Args; - const T ∈ -}; - -template struct IfLt { - StringRef Op; - StringRef Args; - const T ∈ -}; - -static raw_ostream &operator<<(raw_ostream &Stream, const Zero &O) { - Stream << kIndent << "if(size == 0) return"; - if (!O.DefaultReturnValue.empty()) - Stream << ' ' << O.DefaultReturnValue; - return Stream << ";\n"; -} - -template -static raw_ostream &operator<<(raw_ostream &Stream, const IfEq &O) { - return Stream << kIndent << "if(size == " << O.Element.IfEq << ") return " - << O.Op << '<' << O.Element << '>' << O.Args << ";\n"; -} - -template -static raw_ostream &operator<<(raw_ostream &Stream, const IfLt &O) { - Stream << kIndent; - if (O.Element.IfLt != kMaxSize) - Stream << "if(size < " << O.Element.IfLt << ") "; - return Stream << "return " << O.Op << '<' << O.Element << '>' << O.Args - << ";\n"; -} - -static raw_ostream &operator<<(raw_ostream &Stream, - const ElementTypeClass &Class) { - switch (Class) { - case ElementTypeClass::SCALAR: - return Stream << "scalar"; - case ElementTypeClass::BUILTIN: - return Stream << "builtin"; - case ElementTypeClass::NATIVE: - // FIXME: the framework should provide a `native` namespace that redirect to - // x86, arm or other architectures. - return Stream << "x86"; - } -} - -static raw_ostream &operator<<(raw_ostream &Stream, - const FunctionImplementation &FI) { - const auto &Ctx = FI.Ctx; - Stream << "static " << Ctx.FunctionReturnType << ' ' << FI.Name - << Ctx.FunctionArgs << " {\n"; - Stream << kIndent << "using namespace LIBC_NAMESPACE::" << FI.ElementClass - << ";\n"; - for (const auto &I : FI.Individuals) - if (I.Element.Size == 0) - Stream << Zero{Ctx.DefaultReturnValue}; - else - Stream << IfEq{Ctx.ElementOp, Ctx.FixedSizeArgs, I}; - for (const auto &O : FI.Overlaps) - Stream << IfLt{Ctx.ElementOp, Ctx.RuntimeSizeArgs, O}; - if (const auto &C = FI.Loop) - Stream << IfLt{Ctx.ElementOp, Ctx.RuntimeSizeArgs, *C}; - if (const auto &C = FI.AlignedLoop) - Stream << IfLt{Ctx.ElementOp, Ctx.RuntimeSizeArgs, *C}; - if (const auto &C = FI.Accelerator) - Stream << IfLt{Ctx.ElementOp, Ctx.RuntimeSizeArgs, *C}; - return Stream << "}\n"; -} - -// Turns a `NamedFunctionDescriptor` into a `FunctionImplementation` unfolding -// the contiguous and overlap region into several statements. The zero case is -// also mapped to its own type. -static FunctionImplementation -getImplementation(const NamedFunctionDescriptor &NamedFD) { - const FunctionDescriptor &FD = NamedFD.Desc; - FunctionImplementation Impl; - Impl.Ctx = getCtx(FD.Type); - Impl.Name = NamedFD.Name; - Impl.ElementClass = FD.ElementClass; - if (auto C = FD.Contiguous) - for (size_t I = C->Span.Begin; I < C->Span.End; ++I) - Impl.Individuals.push_back(Individual{I, ElementType{I}}); - if (auto C = FD.Overlap) - for (size_t I = C->Span.Begin; I < C->Span.End; I *= 2) - Impl.Overlaps.push_back(Overlap{2 * I, ElementType{I}}); - if (const auto &L = FD.Loop) - Impl.Loop = Loop{L->Span.End, ElementType{L->BlockSize}}; - if (const auto &AL = FD.AlignedLoop) - Impl.AlignedLoop = - AlignedLoop{AL->Loop.Span.End, ElementType{AL->Loop.BlockSize}, - ElementType{AL->Alignment}, getAligntoString(AL->AlignTo)}; - if (const auto &A = FD.Accelerator) - Impl.Accelerator = Accelerator{A->Span.End}; - return Impl; -} - -static void Serialize(raw_ostream &Stream, - ArrayRef Descriptors) { - - for (const auto &FD : Descriptors) - Stream << getImplementation(FD); -} - -} // namespace functions - -namespace descriptors { - -// This namespace generates the getFunctionDescriptors function: -// ------------------------------------------------------------- -// e.g. -// ArrayRef getFunctionDescriptors() { -// static constexpr NamedFunctionDescriptor kDescriptors[] = { -// {"memcpy_0xE00E29EE73994E2B",{FunctionType::MEMCPY,std::nullopt,std::nullopt,std::nullopt,std::nullopt,Accelerator{{0,kMaxSize}},ElementTypeClass::NATIVE}}, -// {"memcpy_0x8661D80472487AB5",{FunctionType::MEMCPY,Contiguous{{0,1}},std::nullopt,std::nullopt,std::nullopt,Accelerator{{1,kMaxSize}},ElementTypeClass::NATIVE}}, -// ... -// }; -// return ArrayRef(kDescriptors); -// } - -static raw_ostream &operator<<(raw_ostream &Stream, const SizeSpan &SS) { - Stream << "{" << SS.Begin << ','; - if (SS.End == kMaxSize) - Stream << "kMaxSize"; - else - Stream << SS.End; - return Stream << '}'; -} -static raw_ostream &operator<<(raw_ostream &Stream, const Contiguous &O) { - return Stream << "Contiguous{" << O.Span << '}'; -} -static raw_ostream &operator<<(raw_ostream &Stream, const Overlap &O) { - return Stream << "Overlap{" << O.Span << '}'; -} -static raw_ostream &operator<<(raw_ostream &Stream, const Loop &O) { - return Stream << "Loop{" << O.Span << ',' << O.BlockSize << '}'; -} -static raw_ostream &operator<<(raw_ostream &Stream, const AlignArg &O) { - switch (O) { - case AlignArg::_1: - return Stream << "AlignArg::_1"; - case AlignArg::_2: - return Stream << "AlignArg::_2"; - case AlignArg::ARRAY_SIZE: - report_fatal_error("logic error"); - } -} -static raw_ostream &operator<<(raw_ostream &Stream, const AlignedLoop &O) { - return Stream << "AlignedLoop{" << O.Loop << ',' << O.Alignment << ',' - << O.AlignTo << '}'; -} -static raw_ostream &operator<<(raw_ostream &Stream, const Accelerator &O) { - return Stream << "Accelerator{" << O.Span << '}'; -} -static raw_ostream &operator<<(raw_ostream &Stream, const ElementTypeClass &O) { - switch (O) { - case ElementTypeClass::SCALAR: - return Stream << "ElementTypeClass::SCALAR"; - case ElementTypeClass::BUILTIN: - return Stream << "ElementTypeClass::BUILTIN"; - case ElementTypeClass::NATIVE: - return Stream << "ElementTypeClass::NATIVE"; - } -} -static raw_ostream &operator<<(raw_ostream &Stream, const FunctionType &T) { - switch (T) { - case FunctionType::MEMCPY: - return Stream << "FunctionType::MEMCPY"; - case FunctionType::MEMCMP: - return Stream << "FunctionType::MEMCMP"; - case FunctionType::BCMP: - return Stream << "FunctionType::BCMP"; - case FunctionType::MEMSET: - return Stream << "FunctionType::MEMSET"; - case FunctionType::BZERO: - return Stream << "FunctionType::BZERO"; - } -} -template -static raw_ostream &operator<<(raw_ostream &Stream, - const std::optional &MaybeT) { - if (MaybeT) - return Stream << *MaybeT; - return Stream << "std::nullopt"; -} -static raw_ostream &operator<<(raw_ostream &Stream, - const FunctionDescriptor &FD) { - return Stream << '{' << FD.Type << ',' << FD.Contiguous << ',' << FD.Overlap - << ',' << FD.Loop << ',' << FD.AlignedLoop << ',' - << FD.Accelerator << ',' << FD.ElementClass << '}'; -} -static raw_ostream &operator<<(raw_ostream &Stream, - const NamedFunctionDescriptor &NFD) { - return Stream << '{' << '"' << NFD.Name << '"' << ',' << NFD.Desc << '}'; -} -template -static raw_ostream &operator<<(raw_ostream &Stream, - const std::vector &VectorT) { - Stream << '{'; - bool First = true; - for (const auto &Obj : VectorT) { - if (!First) - Stream << ','; - Stream << Obj; - First = false; - } - return Stream << '}'; -} - -static void Serialize(raw_ostream &Stream, - ArrayRef Descriptors) { - Stream << R"(ArrayRef getFunctionDescriptors() { - static constexpr NamedFunctionDescriptor kDescriptors[] = { -)"; - for (size_t I = 0, E = Descriptors.size(); I < E; ++I) { - Stream << kIndent << kIndent << Descriptors[I] << ",\n"; - } - Stream << R"( }; - return ArrayRef(kDescriptors); -} -)"; -} - -} // namespace descriptors - -namespace configurations { - -// This namespace generates the getXXXConfigurations functions: -// ------------------------------------------------------------ -// e.g. -// llvm::ArrayRef getMemcpyConfigurations() { -// using namespace LIBC_NAMESPACE; -// static constexpr MemcpyConfiguration kConfigurations[] = { -// {Wrap, "memcpy_0xE00E29EE73994E2B"}, -// {Wrap, "memcpy_0x8661D80472487AB5"}, -// ... -// }; -// return llvm::ArrayRef(kConfigurations); -// } - -// The `Wrap` template function is provided in the `Main` function below. -// It is used to adapt the gnerated code to the prototype of the C function. -// For instance, the generated code for a `memcpy` takes `char*` pointers and -// returns nothing but the original C `memcpy` function take and returns `void*` -// pointers. - -struct FunctionName { - FunctionType ForType; -}; - -struct ReturnType { - FunctionType ForType; -}; - -struct Configuration { - FunctionName Name; - ReturnType Type; - std::vector Descriptors; -}; - -static raw_ostream &operator<<(raw_ostream &Stream, const FunctionName &FN) { - switch (FN.ForType) { - case FunctionType::MEMCPY: - return Stream << "getMemcpyConfigurations"; - case FunctionType::MEMCMP: - return Stream << "getMemcmpConfigurations"; - case FunctionType::BCMP: - return Stream << "getBcmpConfigurations"; - case FunctionType::MEMSET: - return Stream << "getMemsetConfigurations"; - case FunctionType::BZERO: - return Stream << "getBzeroConfigurations"; - } -} - -static raw_ostream &operator<<(raw_ostream &Stream, const ReturnType &RT) { - switch (RT.ForType) { - case FunctionType::MEMCPY: - return Stream << "MemcpyConfiguration"; - case FunctionType::MEMCMP: - case FunctionType::BCMP: - return Stream << "MemcmpOrBcmpConfiguration"; - case FunctionType::MEMSET: - return Stream << "MemsetConfiguration"; - case FunctionType::BZERO: - return Stream << "BzeroConfiguration"; - } -} - -static raw_ostream &operator<<(raw_ostream &Stream, - const NamedFunctionDescriptor *FD) { - return Stream << formatv("{Wrap<{0}>, \"{0}\"}", FD->Name); -} - -static raw_ostream & -operator<<(raw_ostream &Stream, - const std::vector &Descriptors) { - for (size_t I = 0, E = Descriptors.size(); I < E; ++I) - Stream << kIndent << kIndent << Descriptors[I] << ",\n"; - return Stream; -} - -static raw_ostream &operator<<(raw_ostream &Stream, const Configuration &C) { - Stream << "llvm::ArrayRef<" << C.Type << "> " << C.Name << "() {\n"; - if (C.Descriptors.empty()) - Stream << kIndent << "return {};\n"; - else { - Stream << kIndent << "using namespace LIBC_NAMESPACE;\n"; - Stream << kIndent << "static constexpr " << C.Type - << " kConfigurations[] = {\n"; - Stream << C.Descriptors; - Stream << kIndent << "};\n"; - Stream << kIndent << "return llvm::ArrayRef(kConfigurations);\n"; - } - Stream << "}\n"; - return Stream; -} - -static void Serialize(raw_ostream &Stream, FunctionType FT, - ArrayRef Descriptors) { - Configuration Conf; - Conf.Name = {FT}; - Conf.Type = {FT}; - for (const auto &FD : Descriptors) - if (FD.Desc.Type == FT) - Conf.Descriptors.push_back(&FD); - Stream << Conf; -} - -} // namespace configurations -static void Serialize(raw_ostream &Stream, - ArrayRef Descriptors) { - Stream << "// This file is auto-generated by libc/benchmarks/automemcpy.\n"; - Stream << "// Functions : " << Descriptors.size() << "\n"; - Stream << "\n"; - Stream << "#include \"LibcFunctionPrototypes.h\"\n"; - Stream << "#include \"automemcpy/FunctionDescriptor.h\"\n"; - Stream << "#include \"src/string/memory_utils/elements.h\"\n"; - Stream << "\n"; - Stream << "using llvm::libc_benchmarks::BzeroConfiguration;\n"; - Stream << "using llvm::libc_benchmarks::MemcmpOrBcmpConfiguration;\n"; - Stream << "using llvm::libc_benchmarks::MemcpyConfiguration;\n"; - Stream << "using llvm::libc_benchmarks::MemmoveConfiguration;\n"; - Stream << "using llvm::libc_benchmarks::MemsetConfiguration;\n"; - Stream << "\n"; - Stream << "namespace LIBC_NAMESPACE_DECL {\n"; - Stream << "\n"; - codegen::functions::Serialize(Stream, Descriptors); - Stream << "\n"; - Stream << "} // namespace LIBC_NAMESPACE_DECL\n"; - Stream << "\n"; - Stream << "namespace llvm {\n"; - Stream << "namespace automemcpy {\n"; - Stream << "\n"; - codegen::descriptors::Serialize(Stream, Descriptors); - Stream << "\n"; - Stream << "} // namespace automemcpy\n"; - Stream << "} // namespace llvm\n"; - Stream << "\n"; - Stream << R"( -using MemcpyStub = void (*)(char *__restrict, const char *__restrict, size_t); -template -void *Wrap(void *__restrict dst, const void *__restrict src, size_t size) { - Foo(reinterpret_cast(dst), - reinterpret_cast(src), size); - return dst; -} -)"; - codegen::configurations::Serialize(Stream, FunctionType::MEMCPY, Descriptors); - Stream << R"( -using MemcmpStub = int (*)(const char *, const char *, size_t); -template -int Wrap(const void *lhs, const void *rhs, size_t size) { - return Foo(reinterpret_cast(lhs), - reinterpret_cast(rhs), size); -} -)"; - codegen::configurations::Serialize(Stream, FunctionType::MEMCMP, Descriptors); - codegen::configurations::Serialize(Stream, FunctionType::BCMP, Descriptors); - Stream << R"( -using MemsetStub = void (*)(char *, int, size_t); -template void *Wrap(void *dst, int value, size_t size) { - Foo(reinterpret_cast(dst), value, size); - return dst; -} -)"; - codegen::configurations::Serialize(Stream, FunctionType::MEMSET, Descriptors); - Stream << R"( -using BzeroStub = void (*)(char *, size_t); -template void Wrap(void *dst, size_t size) { - Foo(reinterpret_cast(dst), size); -} -)"; - codegen::configurations::Serialize(Stream, FunctionType::BZERO, Descriptors); - Stream << R"( -llvm::ArrayRef getMemmoveConfigurations() { - return {}; -} -)"; - Stream << "// Functions : " << Descriptors.size() << "\n"; -} - -} // namespace codegen - -// Stores `VolatileStr` into a cache and returns a StringRef of the cached -// version. -StringRef getInternalizedString(std::string VolatileStr) { - static llvm::StringSet StringCache; - return StringCache.insert(std::move(VolatileStr)).first->getKey(); -} - -static StringRef getString(FunctionType FT) { - switch (FT) { - case FunctionType::MEMCPY: - return "memcpy"; - case FunctionType::MEMCMP: - return "memcmp"; - case FunctionType::BCMP: - return "bcmp"; - case FunctionType::MEMSET: - return "memset"; - case FunctionType::BZERO: - return "bzero"; - } -} - -void Serialize(raw_ostream &Stream, ArrayRef Descriptors) { - std::vector FunctionDescriptors; - FunctionDescriptors.reserve(Descriptors.size()); - for (auto &FD : Descriptors) { - FunctionDescriptors.emplace_back(); - FunctionDescriptors.back().Name = getInternalizedString( - formatv("{0}_{1:X16}", getString(FD.Type), FD.id())); - FunctionDescriptors.back().Desc = std::move(FD); - } - // Sort functions so they are easier to spot in the generated C++ file. - std::sort(FunctionDescriptors.begin(), FunctionDescriptors.end(), - [](const NamedFunctionDescriptor &A, - const NamedFunctionDescriptor &B) { return A.Desc < B.Desc; }); - codegen::Serialize(Stream, FunctionDescriptors); -} - -} // namespace automemcpy -} // namespace llvm diff --git a/libc/benchmarks/automemcpy/lib/CodeGenMain.cpp b/libc/benchmarks/automemcpy/lib/CodeGenMain.cpp deleted file mode 100644 index 3f4e6fc0423a1..0000000000000 --- a/libc/benchmarks/automemcpy/lib/CodeGenMain.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "automemcpy/CodeGen.h" -#include "automemcpy/RandomFunctionGenerator.h" -#include -#include - -namespace llvm { -namespace automemcpy { - -std::vector generateFunctionDescriptors() { - std::unordered_set Seen; - std::vector FunctionDescriptors; - RandomFunctionGenerator P; - while (std::optional MaybeFD = P.next()) { - FunctionDescriptor FD = *MaybeFD; - if (Seen.count(FD)) // FIXME: Z3 sometimes returns twice the same object. - continue; - Seen.insert(FD); - FunctionDescriptors.push_back(std::move(FD)); - } - return FunctionDescriptors; -} - -} // namespace automemcpy -} // namespace llvm - -int main(int, char **) { - llvm::automemcpy::Serialize(llvm::outs(), - llvm::automemcpy::generateFunctionDescriptors()); -} diff --git a/libc/benchmarks/automemcpy/lib/RandomFunctionGenerator.cpp b/libc/benchmarks/automemcpy/lib/RandomFunctionGenerator.cpp deleted file mode 100644 index f438e2a405bd0..0000000000000 --- a/libc/benchmarks/automemcpy/lib/RandomFunctionGenerator.cpp +++ /dev/null @@ -1,280 +0,0 @@ -//===-- Generate random but valid function descriptors -------------------===// -// -// 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 "automemcpy/RandomFunctionGenerator.h" - -#include -#include - -#include -#include - -namespace llvm { -namespace automemcpy { - -// Exploration parameters -// ---------------------- -// Here we define a set of values that will contraint the exploration and -// limit combinatorial explosion. - -// We limit the number of cases for individual sizes to sizes up to 4. -// More individual sizes don't bring much over the overlapping strategy. -static constexpr int kMaxIndividualSize = 4; - -// We limit Overlapping Strategy to sizes up to 256. -// An overlap of 256B means accessing 128B at once which is usually not -// feasible by current CPUs. We rely on the compiler to generate multiple -// loads/stores if needed but higher sizes are unlikely to benefit from hardware -// acceleration. -static constexpr int kMaxOverlapSize = 256; - -// For the loop strategies, we make sure that they iterate at least a certain -// number of times to amortize the cost of looping. -static constexpr int kLoopMinIter = 3; -static constexpr int kAlignedLoopMinIter = 2; - -// We restrict the size of the block of data to handle in a loop. -// Generally speaking block size <= 16 perform poorly. -static constexpr int kLoopBlockSize[] = {16, 32, 64}; - -// We restrict alignment to the following values. -static constexpr int kLoopAlignments[] = {16, 32, 64}; - -// We make sure that the region bounds are one of the following values. -static constexpr int kAnchors[] = {0, 1, 2, 4, 8, 16, 32, 48, - 64, 96, 128, 256, 512, 1024, kMaxSize}; - -// We also allow disabling loops, aligned loops and accelerators. -static constexpr bool kDisableLoop = false; -static constexpr bool kDisableAlignedLoop = false; -static constexpr bool kDisableAccelerator = false; - -// For memcpy, we can also explore whether aligning on source or destination has -// an effect. -static constexpr bool kExploreAlignmentArg = true; - -// The function we generate code for. -// BCMP is specifically disabled for now. -static constexpr int kFunctionTypes[] = { - (int)FunctionType::MEMCPY, - (int)FunctionType::MEMCMP, - // (int)FunctionType::BCMP, - (int)FunctionType::MEMSET, - (int)FunctionType::BZERO, -}; - -// The actual implementation of each function can be handled via primitive types -// (SCALAR), vector types where available (NATIVE) or by the compiler (BUILTIN). -// We want to move toward delegating the code generation entirely to the -// compiler but for now we have to make use of -per microarchitecture- custom -// implementations. Scalar being more portable but also less performant, we -// remove it as well. -static constexpr int kElementClasses[] = { - // (int)ElementTypeClass::SCALAR, - (int)ElementTypeClass::NATIVE, - // (int)ElementTypeClass::BUILTIN -}; - -RandomFunctionGenerator::RandomFunctionGenerator() - : Solver(Context), Type(Context.int_const("Type")), - ContiguousBegin(Context.int_const("ContiguousBegin")), - ContiguousEnd(Context.int_const("ContiguousEnd")), - OverlapBegin(Context.int_const("OverlapBegin")), - OverlapEnd(Context.int_const("OverlapEnd")), - LoopBegin(Context.int_const("LoopBegin")), - LoopEnd(Context.int_const("LoopEnd")), - LoopBlockSize(Context.int_const("LoopBlockSize")), - AlignedLoopBegin(Context.int_const("AlignedLoopBegin")), - AlignedLoopEnd(Context.int_const("AlignedLoopEnd")), - AlignedLoopBlockSize(Context.int_const("AlignedLoopBlockSize")), - AlignedAlignment(Context.int_const("AlignedAlignment")), - AlignedArg(Context.int_const("AlignedArg")), - AcceleratorBegin(Context.int_const("AcceleratorBegin")), - AcceleratorEnd(Context.int_const("AcceleratorEnd")), - ElementClass(Context.int_const("ElementClass")) { - // All possible functions. - Solver.add(inSetConstraint(Type, kFunctionTypes)); - - // Add constraints for region bounds. - addBoundsAndAnchors(ContiguousBegin, ContiguousEnd); - addBoundsAndAnchors(OverlapBegin, OverlapEnd); - addBoundsAndAnchors(LoopBegin, LoopEnd); - addBoundsAndAnchors(AlignedLoopBegin, AlignedLoopEnd); - addBoundsAndAnchors(AcceleratorBegin, AcceleratorEnd); - // We always consider strategies in this order, and we - // always end with the `Accelerator` strategy, as it's typically more - // efficient for large sizes. - // Contiguous <= Overlap <= Loop <= AlignedLoop <= Accelerator - Solver.add(ContiguousEnd == OverlapBegin); - Solver.add(OverlapEnd == LoopBegin); - Solver.add(LoopEnd == AlignedLoopBegin); - Solver.add(AlignedLoopEnd == AcceleratorBegin); - // Fix endpoints: The minimum size that we want to copy is 0, and we always - // start with the `Contiguous` strategy. The max size is `kMaxSize`. - Solver.add(ContiguousBegin == 0); - Solver.add(AcceleratorEnd == kMaxSize); - // Contiguous - Solver.add(ContiguousEnd <= kMaxIndividualSize + 1); - // Overlap - Solver.add(OverlapEnd <= kMaxOverlapSize + 1); - // Overlap only ever makes sense when accessing multiple bytes at a time. - // i.e. Overlap<1> is useless. - Solver.add(OverlapBegin == OverlapEnd || OverlapBegin >= 2); - // Loop - addLoopConstraints(LoopBegin, LoopEnd, LoopBlockSize, kLoopMinIter); - // Aligned Loop - addLoopConstraints(AlignedLoopBegin, AlignedLoopEnd, AlignedLoopBlockSize, - kAlignedLoopMinIter); - Solver.add(inSetConstraint(AlignedAlignment, kLoopAlignments)); - Solver.add(AlignedLoopBegin == AlignedLoopEnd || AlignedLoopBegin >= 64); - Solver.add(AlignedLoopBlockSize >= AlignedAlignment); - Solver.add(AlignedLoopBlockSize >= LoopBlockSize); - z3::expr IsMemcpy = Type == (int)FunctionType::MEMCPY; - z3::expr ExploreAlignment = IsMemcpy && kExploreAlignmentArg; - Solver.add( - (ExploreAlignment && - inSetConstraint(AlignedArg, {(int)AlignArg::_1, (int)AlignArg::_2})) || - (!ExploreAlignment && AlignedArg == (int)AlignArg::_1)); - // Accelerator - Solver.add(IsMemcpy || - (AcceleratorBegin == - AcceleratorEnd)); // Only Memcpy has accelerator for now. - // Element classes - Solver.add(inSetConstraint(ElementClass, kElementClasses)); - - if (kDisableLoop) - Solver.add(LoopBegin == LoopEnd); - if (kDisableAlignedLoop) - Solver.add(AlignedLoopBegin == AlignedLoopEnd); - if (kDisableAccelerator) - Solver.add(AcceleratorBegin == AcceleratorEnd); -} - -// Creates SizeSpan from Begin/End values. -// Returns std::nullopt if Begin==End. -static std::optional AsSizeSpan(size_t Begin, size_t End) { - if (Begin == End) - return std::nullopt; - SizeSpan SS; - SS.Begin = Begin; - SS.End = End; - return SS; -} - -// Generic method to create a `Region` struct with a Span or std::nullopt if -// span is empty. -template -static std::optional As(size_t Begin, size_t End) { - if (auto Span = AsSizeSpan(Begin, End)) { - Region Output; - Output.Span = *Span; - return Output; - } - return std::nullopt; -} - -// Returns a Loop struct or std::nullopt if span is empty. -static std::optional AsLoop(size_t Begin, size_t End, size_t BlockSize) { - if (auto Span = AsSizeSpan(Begin, End)) { - Loop Output; - Output.Span = *Span; - Output.BlockSize = BlockSize; - return Output; - } - return std::nullopt; -} - -// Returns an AlignedLoop struct or std::nullopt if span is empty. -static std::optional AsAlignedLoop(size_t Begin, size_t End, - size_t BlockSize, - size_t Alignment, - AlignArg AlignTo) { - if (auto Loop = AsLoop(Begin, End, BlockSize)) { - AlignedLoop Output; - Output.Loop = *Loop; - Output.Alignment = Alignment; - Output.AlignTo = AlignTo; - return Output; - } - return std::nullopt; -} - -std::optional RandomFunctionGenerator::next() { - if (Solver.check() != z3::sat) - return {}; - - z3::model m = Solver.get_model(); - - // Helper method to get the current numerical value of a z3::expr. - const auto E = [&m](z3::expr &V) -> int { - return m.eval(V).get_numeral_int(); - }; - - // Fill is the function descriptor to return. - FunctionDescriptor R; - R.Type = FunctionType(E(Type)); - R.Contiguous = As(E(ContiguousBegin), E(ContiguousEnd)); - R.Overlap = As(E(OverlapBegin), E(OverlapEnd)); - R.Loop = AsLoop(E(LoopBegin), E(LoopEnd), E(LoopBlockSize)); - R.AlignedLoop = AsAlignedLoop(E(AlignedLoopBegin), E(AlignedLoopEnd), - E(AlignedLoopBlockSize), E(AlignedAlignment), - AlignArg(E(AlignedArg))); - R.Accelerator = As(E(AcceleratorBegin), E(AcceleratorEnd)); - R.ElementClass = ElementTypeClass(E(ElementClass)); - - // Express current state as a set of constraints. - z3::expr CurrentLayout = - (Type == E(Type)) && (ContiguousBegin == E(ContiguousBegin)) && - (ContiguousEnd == E(ContiguousEnd)) && - (OverlapBegin == E(OverlapBegin)) && (OverlapEnd == E(OverlapEnd)) && - (LoopBegin == E(LoopBegin)) && (LoopEnd == E(LoopEnd)) && - (LoopBlockSize == E(LoopBlockSize)) && - (AlignedLoopBegin == E(AlignedLoopBegin)) && - (AlignedLoopEnd == E(AlignedLoopEnd)) && - (AlignedLoopBlockSize == E(AlignedLoopBlockSize)) && - (AlignedAlignment == E(AlignedAlignment)) && - (AlignedArg == E(AlignedArg)) && - (AcceleratorBegin == E(AcceleratorBegin)) && - (AcceleratorEnd == E(AcceleratorEnd)) && - (ElementClass == E(ElementClass)); - - // Ask solver to never show this configuration ever again. - Solver.add(!CurrentLayout); - return R; -} - -// Make sure `Variable` is one of the provided values. -z3::expr RandomFunctionGenerator::inSetConstraint(z3::expr &Variable, - ArrayRef Values) const { - z3::expr_vector Args(Variable.ctx()); - for (int Value : Values) - Args.push_back(Variable == Value); - return z3::mk_or(Args); -} - -void RandomFunctionGenerator::addBoundsAndAnchors(z3::expr &Begin, - z3::expr &End) { - // Begin and End are picked amongst a set of predefined values. - Solver.add(inSetConstraint(Begin, kAnchors)); - Solver.add(inSetConstraint(End, kAnchors)); - Solver.add(Begin >= 0); - Solver.add(Begin <= End); - Solver.add(End <= kMaxSize); -} - -void RandomFunctionGenerator::addLoopConstraints(const z3::expr &LoopBegin, - const z3::expr &LoopEnd, - z3::expr &LoopBlockSize, - int LoopMinIter) { - Solver.add(inSetConstraint(LoopBlockSize, kLoopBlockSize)); - Solver.add(LoopBegin == LoopEnd || - (LoopBegin > (LoopMinIter * LoopBlockSize))); -} - -} // namespace automemcpy -} // namespace llvm diff --git a/libc/benchmarks/automemcpy/lib/ResultAnalyzer.cpp b/libc/benchmarks/automemcpy/lib/ResultAnalyzer.cpp deleted file mode 100644 index b134f6c83a0df..0000000000000 --- a/libc/benchmarks/automemcpy/lib/ResultAnalyzer.cpp +++ /dev/null @@ -1,204 +0,0 @@ -//===-- Analyze benchmark JSON files --------------------------------------===// -// -// 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 code analyzes the json file produced by the `automemcpy` binary. -// -// As a remainder, `automemcpy` will benchmark each autogenerated memory -// functions against one of the predefined distributions available in the -// `libc/benchmarks/distributions` folder. -// -// It works as follows: -// - Reads one or more json files. -// - If there are several runs for the same function and distribution, picks the -// median throughput (aka `BytesPerSecond`). -// - Aggregates the throughput per distributions and scores them from worst (0) -// to best (1). -// - Each distribution categorizes each function into one of the following -// categories: EXCELLENT, VERY_GOOD, GOOD, PASSABLE, INADEQUATE, MEDIOCRE, -// BAD. -// - A process similar to the Majority Judgment voting system is used to `elect` -// the best function. The histogram of grades is returned so we can -// distinguish between functions with the same final grade. In the following -// example both functions grade EXCELLENT but we may prefer the second one. -// -// | | EXCELLENT | VERY_GOOD | GOOD | PASSABLE | ... -// |------------|-----------|-----------|------|----------| ... -// | Function_1 | 7 | 1 | 2 | | ... -// | Function_2 | 6 | 4 | | | ... - -#include "automemcpy/ResultAnalyzer.h" -#include "llvm/ADT/StringRef.h" -#include -#include - -namespace llvm { - -namespace automemcpy { - -StringRef Grade::getString(const GradeEnum &GE) { - switch (GE) { - case EXCELLENT: - return "EXCELLENT"; - case VERY_GOOD: - return "VERY_GOOD"; - case GOOD: - return "GOOD"; - case PASSABLE: - return "PASSABLE"; - case INADEQUATE: - return "INADEQUATE"; - case MEDIOCRE: - return "MEDIOCRE"; - case BAD: - return "BAD"; - case ARRAY_SIZE: - report_fatal_error("logic error"); - } -} - -Grade::GradeEnum Grade::judge(double Score) { - if (Score >= 6. / 7) - return EXCELLENT; - if (Score >= 5. / 7) - return VERY_GOOD; - if (Score >= 4. / 7) - return GOOD; - if (Score >= 3. / 7) - return PASSABLE; - if (Score >= 2. / 7) - return INADEQUATE; - if (Score >= 1. / 7) - return MEDIOCRE; - return BAD; -} - -static double computeUnbiasedSampleVariance(const std::vector &Samples, - const double SampleMean) { - assert(!Samples.empty()); - if (Samples.size() == 1) - return 0; - double DiffSquaresSum = 0; - for (const double S : Samples) { - const double Diff = S - SampleMean; - DiffSquaresSum += Diff * Diff; - } - return DiffSquaresSum / (Samples.size() - 1); -} - -static void processPerDistributionData(PerDistributionData &Data) { - auto &Samples = Data.BytesPerSecondSamples; - assert(!Samples.empty()); - // Sample Mean - const double Sum = std::accumulate(Samples.begin(), Samples.end(), 0.0); - Data.BytesPerSecondMean = Sum / Samples.size(); - // Unbiased Sample Variance - Data.BytesPerSecondVariance = - computeUnbiasedSampleVariance(Samples, Data.BytesPerSecondMean); - // Median - const size_t HalfSize = Samples.size() / 2; - std::nth_element(Samples.begin(), Samples.begin() + HalfSize, Samples.end()); - Data.BytesPerSecondMedian = Samples[HalfSize]; -} - -std::vector getThroughputs(ArrayRef Samples) { - std::unordered_map Functions; - for (const auto &S : Samples) { - if (S.Type != SampleType::ITERATION) - break; - auto &Function = Functions[S.Id.Function]; - auto &Data = Function.PerDistributionData[S.Id.Distribution.Name]; - Data.BytesPerSecondSamples.push_back(S.BytesPerSecond); - } - - std::vector Output; - for (auto &[FunctionId, Function] : Functions) { - Function.Id = FunctionId; - for (auto &Pair : Function.PerDistributionData) - processPerDistributionData(Pair.second); - Output.push_back(std::move(Function)); - } - return Output; -} - -void fillScores(MutableArrayRef Functions) { - // A key to bucket throughput per function type and distribution. - struct Key { - FunctionType Type; - StringRef Distribution; - - COMPARABLE_AND_HASHABLE(Key, Type, Distribution) - }; - - // Tracks minimum and maximum values. - struct MinMax { - double Min = std::numeric_limits::max(); - double Max = std::numeric_limits::min(); - void update(double Value) { - if (Value < Min) - Min = Value; - if (Value > Max) - Max = Value; - } - double normalize(double Value) const { return (Value - Min) / (Max - Min); } - }; - - std::unordered_map ThroughputMinMax; - for (const auto &Function : Functions) { - const FunctionType Type = Function.Id.Type; - for (const auto &Pair : Function.PerDistributionData) { - const auto &Distribution = Pair.getKey(); - const double Throughput = Pair.getValue().BytesPerSecondMedian; - const Key K{Type, Distribution}; - ThroughputMinMax[K].update(Throughput); - } - } - - for (auto &Function : Functions) { - const FunctionType Type = Function.Id.Type; - for (const auto &Pair : Function.PerDistributionData) { - const auto &Distribution = Pair.getKey(); - const double Throughput = Pair.getValue().BytesPerSecondMedian; - const Key K{Type, Distribution}; - Function.PerDistributionData[Distribution].Score = - ThroughputMinMax[K].normalize(Throughput); - } - } -} - -void castVotes(MutableArrayRef Functions) { - for (FunctionData &Function : Functions) { - Function.ScoresGeoMean = 1.0; - for (const auto &Pair : Function.PerDistributionData) { - const StringRef Distribution = Pair.getKey(); - const double Score = Pair.getValue().Score; - Function.ScoresGeoMean *= Score; - const auto G = Grade::judge(Score); - ++(Function.GradeHisto[G]); - Function.PerDistributionData[Distribution].Grade = G; - } - } - - for (FunctionData &Function : Functions) { - const auto &GradeHisto = Function.GradeHisto; - const size_t Votes = - std::accumulate(GradeHisto.begin(), GradeHisto.end(), 0U); - const size_t MedianVote = Votes / 2; - size_t CountedVotes = 0; - Grade::GradeEnum MedianGrade = Grade::BAD; - for (size_t I = 0; I < GradeHisto.size(); ++I) { - CountedVotes += GradeHisto[I]; - if (CountedVotes > MedianVote) { - MedianGrade = Grade::GradeEnum(I); - break; - } - } - Function.FinalGrade = MedianGrade; - } -} - -} // namespace automemcpy -} // namespace llvm diff --git a/libc/benchmarks/automemcpy/lib/ResultAnalyzerMain.cpp b/libc/benchmarks/automemcpy/lib/ResultAnalyzerMain.cpp deleted file mode 100644 index 00eef73a3f38a..0000000000000 --- a/libc/benchmarks/automemcpy/lib/ResultAnalyzerMain.cpp +++ /dev/null @@ -1,175 +0,0 @@ -//===-- Application to analyze benchmark JSON files -----------------------===// -// -// 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 "automemcpy/ResultAnalyzer.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/JSON.h" -#include "llvm/Support/MemoryBuffer.h" - -namespace llvm { - -// User can specify one or more json filenames to process on the command line. -static cl::list InputFilenames(cl::Positional, cl::OneOrMore, - cl::desc("")); - -// User can filter the distributions to be taken into account. -static cl::list - KeepOnlyDistributions("keep-only-distributions", - cl::desc("")); - -namespace automemcpy { - -// This is defined in the autogenerated 'Implementations.cpp' file. -extern ArrayRef getFunctionDescriptors(); - -// Iterates over all functions and fills a map of function name to function -// descriptor pointers. -static StringMap createFunctionDescriptorMap() { - StringMap Descriptors; - for (const NamedFunctionDescriptor &FD : getFunctionDescriptors()) - Descriptors.insert_or_assign(FD.Name, &FD.Desc); - return Descriptors; -} - -// Retrieves the function descriptor for a particular function name. -static const FunctionDescriptor &getFunctionDescriptor(StringRef FunctionName) { - static StringMap Descriptors = - createFunctionDescriptorMap(); - const auto *FD = Descriptors.lookup(FunctionName); - if (!FD) - report_fatal_error( - Twine("No FunctionDescriptor for ").concat(FunctionName)); - return *FD; -} - -// Functions and distributions names are stored quite a few times so it's more -// efficient to internalize these strings and refer to them through 'StringRef'. -static StringRef getInternalizedString(StringRef VolatileStr) { - static llvm::StringSet StringCache; - return StringCache.insert(VolatileStr).first->getKey(); -} - -// Helper function for the LLVM JSON API. -bool fromJSON(const json::Value &V, Sample &Out, json::Path P) { - std::string Label; - std::string RunType; - json::ObjectMapper O(V, P); - if (O && O.map("bytes_per_second", Out.BytesPerSecond) && - O.map("run_type", RunType) && O.map("label", Label)) { - const auto LabelPair = StringRef(Label).split(','); - Out.Id.Function.Name = getInternalizedString(LabelPair.first); - Out.Id.Function.Type = getFunctionDescriptor(LabelPair.first).Type; - Out.Id.Distribution.Name = getInternalizedString(LabelPair.second); - Out.Type = StringSwitch(RunType) - .Case("aggregate", SampleType::AGGREGATE) - .Case("iteration", SampleType::ITERATION); - return true; - } - return false; -} - -// An object to represent the content of the JSON file. -// This is easier to parse/serialize JSON when the structures of the json file -// maps the structure of the object. -struct JsonFile { - std::vector Samples; -}; - -// Helper function for the LLVM JSON API. -bool fromJSON(const json::Value &V, JsonFile &JF, json::Path P) { - json::ObjectMapper O(V, P); - return O && O.map("benchmarks", JF.Samples); -} - -// Global object to ease error reporting, it consumes errors and crash the -// application with a meaningful message. -static ExitOnError ExitOnErr; - -// Main JSON parsing method. Reads the content of the file pointed to by -// 'Filename' and returns a JsonFile object. -JsonFile parseJsonResultFile(StringRef Filename) { - auto Buf = ExitOnErr(errorOrToExpected( - MemoryBuffer::getFile(Filename, /*bool IsText=*/true, - /*RequiresNullTerminator=*/false))); - auto JsonValue = ExitOnErr(json::parse(Buf->getBuffer())); - json::Path::Root Root; - JsonFile JF; - if (!fromJSON(JsonValue, JF, Root)) - ExitOnErr(Root.getError()); - return JF; -} - -// Serializes the 'GradeHisto' to the provided 'Stream'. -static void Serialize(raw_ostream &Stream, const GradeHistogram &GH) { - static constexpr std::array kCharacters = { - " ", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"}; - - const size_t Max = *std::max_element(GH.begin(), GH.end()); - for (size_t I = 0; I < GH.size(); ++I) { - size_t Index = (float(GH[I]) / Max) * (kCharacters.size() - 1); - Stream << kCharacters.at(Index); - } -} - -int Main(int argc, char **argv) { - ExitOnErr.setBanner("Automemcpy Json Results Analyzer stopped with error: "); - cl::ParseCommandLineOptions(argc, argv, "Automemcpy Json Results Analyzer\n"); - - // Reads all samples stored in the input JSON files. - std::vector Samples; - for (const auto &Filename : InputFilenames) { - auto Result = parseJsonResultFile(Filename); - llvm::append_range(Samples, Result.Samples); - } - - if (!KeepOnlyDistributions.empty()) { - llvm::StringSet ValidDistributions; - ValidDistributions.insert(KeepOnlyDistributions.begin(), - KeepOnlyDistributions.end()); - llvm::erase_if(Samples, [&ValidDistributions](const Sample &S) { - return !ValidDistributions.contains(S.Id.Distribution.Name); - }); - } - - // Extracts median of throughputs. - std::vector Functions = getThroughputs(Samples); - fillScores(Functions); - castVotes(Functions); - - // Present data by function type, Grade and Geomean of scores. - std::sort(Functions.begin(), Functions.end(), - [](const FunctionData &A, const FunctionData &B) { - const auto Less = [](const FunctionData &FD) { - return std::make_tuple(FD.Id.Type, FD.FinalGrade, - -FD.ScoresGeoMean); - }; - return Less(A) < Less(B); - }); - - // Print result. - for (const FunctionData &Function : Functions) { - outs() << formatv("{0,-10}", Grade::getString(Function.FinalGrade)); - outs() << " |"; - Serialize(outs(), Function.GradeHisto); - outs() << "| "; - outs().resetColor(); - outs() << formatv("{0,+25}", Function.Id.Name); - outs() << "\n"; - } - - return EXIT_SUCCESS; -} - -} // namespace automemcpy -} // namespace llvm - -int main(int argc, char **argv) { return llvm::automemcpy::Main(argc, argv); } diff --git a/libc/benchmarks/automemcpy/unittests/CMakeLists.txt b/libc/benchmarks/automemcpy/unittests/CMakeLists.txt deleted file mode 100644 index 35caaac1519ba..0000000000000 --- a/libc/benchmarks/automemcpy/unittests/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -add_libc_benchmark_unittest(libc-automemcpy-codegen-test - SRCS CodeGenTest.cpp - DEPENDS automemcpy_codegen -) - -add_libc_benchmark_unittest(libc-automemcpy-result-analyzer-test - SRCS ResultAnalyzerTest.cpp - DEPENDS automemcpy_result_analyzer_lib -) diff --git a/libc/benchmarks/automemcpy/unittests/CodeGenTest.cpp b/libc/benchmarks/automemcpy/unittests/CodeGenTest.cpp deleted file mode 100644 index a7fc8570a73b0..0000000000000 --- a/libc/benchmarks/automemcpy/unittests/CodeGenTest.cpp +++ /dev/null @@ -1,226 +0,0 @@ -//===-- Automemcpy CodeGen Test -------------------------------------------===// -// -// 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 "automemcpy/CodeGen.h" -#include "automemcpy/RandomFunctionGenerator.h" -#include "src/__support/macros/config.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" -#include - -using testing::AllOf; -using testing::AnyOf; -using testing::ElementsAre; -using testing::Ge; -using testing::Gt; -using testing::Le; -using testing::Lt; - -namespace llvm { -namespace automemcpy { -namespace { - -TEST(Automemcpy, Codegen) { - static constexpr FunctionDescriptor kDescriptors[] = { - {FunctionType::MEMCPY, std::nullopt, std::nullopt, std::nullopt, std::nullopt, - Accelerator{{0, kMaxSize}}, ElementTypeClass::NATIVE}, - {FunctionType::MEMCPY, Contiguous{{0, 4}}, Overlap{{4, 256}}, - Loop{{256, kMaxSize}, 64}, std::nullopt, std::nullopt, - ElementTypeClass::NATIVE}, - {FunctionType::MEMCMP, Contiguous{{0, 2}}, Overlap{{2, 64}}, std::nullopt, - AlignedLoop{Loop{{64, kMaxSize}, 16}, 16, AlignArg::_1}, std::nullopt, - ElementTypeClass::NATIVE}, - {FunctionType::MEMSET, Contiguous{{0, 2}}, Overlap{{2, 256}}, std::nullopt, - AlignedLoop{Loop{{256, kMaxSize}, 32}, 16, AlignArg::_1}, std::nullopt, - ElementTypeClass::NATIVE}, - {FunctionType::MEMSET, Contiguous{{0, 2}}, Overlap{{2, 256}}, std::nullopt, - AlignedLoop{Loop{{256, kMaxSize}, 32}, 32, AlignArg::_1}, std::nullopt, - ElementTypeClass::NATIVE}, - {FunctionType::BZERO, Contiguous{{0, 4}}, Overlap{{4, 128}}, std::nullopt, - AlignedLoop{Loop{{128, kMaxSize}, 32}, 32, AlignArg::_1}, std::nullopt, - ElementTypeClass::NATIVE}, - }; - - std::string Output; - raw_string_ostream OutputStream(Output); - Serialize(OutputStream, kDescriptors); - - EXPECT_STREQ(Output.c_str(), - R"(// This file is auto-generated by libc/benchmarks/automemcpy. -// Functions : 6 - -#include "LibcFunctionPrototypes.h" -#include "automemcpy/FunctionDescriptor.h" -#include "src/string/memory_utils/elements.h" - -using llvm::libc_benchmarks::BzeroConfiguration; -using llvm::libc_benchmarks::MemcmpOrBcmpConfiguration; -using llvm::libc_benchmarks::MemcpyConfiguration; -using llvm::libc_benchmarks::MemmoveConfiguration; -using llvm::libc_benchmarks::MemsetConfiguration; - -namespace LIBC_NAMESPACE_DECL { - -static void memcpy_0xE00E29EE73994E2B(char *__restrict dst, const char *__restrict src, size_t size) { - using namespace LIBC_NAMESPACE::x86; - return copy(dst, src, size); -} -static void memcpy_0x7381B60C7BE75EF9(char *__restrict dst, const char *__restrict src, size_t size) { - using namespace LIBC_NAMESPACE::x86; - if(size == 0) return; - if(size == 1) return copy<_1>(dst, src); - if(size == 2) return copy<_2>(dst, src); - if(size == 3) return copy<_3>(dst, src); - if(size < 8) return copy>(dst, src, size); - if(size < 16) return copy>(dst, src, size); - if(size < 32) return copy>(dst, src, size); - if(size < 64) return copy>(dst, src, size); - if(size < 128) return copy>(dst, src, size); - if(size < 256) return copy>(dst, src, size); - return copy>(dst, src, size); -} -static int memcmp_0x348D7BA6DB0EE033(const char * lhs, const char * rhs, size_t size) { - using namespace LIBC_NAMESPACE::x86; - if(size == 0) return 0; - if(size == 1) return three_way_compare<_1>(lhs, rhs); - if(size < 4) return three_way_compare>(lhs, rhs, size); - if(size < 8) return three_way_compare>(lhs, rhs, size); - if(size < 16) return three_way_compare>(lhs, rhs, size); - if(size < 32) return three_way_compare>(lhs, rhs, size); - if(size < 64) return three_way_compare>(lhs, rhs, size); - return three_way_compare::Then>>(lhs, rhs, size); -} -static void memset_0x71E761699B999863(char * dst, int value, size_t size) { - using namespace LIBC_NAMESPACE::x86; - if(size == 0) return; - if(size == 1) return splat_set<_1>(dst, value); - if(size < 4) return splat_set>(dst, value, size); - if(size < 8) return splat_set>(dst, value, size); - if(size < 16) return splat_set>(dst, value, size); - if(size < 32) return splat_set>(dst, value, size); - if(size < 64) return splat_set>(dst, value, size); - if(size < 128) return splat_set>(dst, value, size); - if(size < 256) return splat_set>(dst, value, size); - return splat_set::Then>>(dst, value, size); -} -static void memset_0x3DF0F44E2ED6A50F(char * dst, int value, size_t size) { - using namespace LIBC_NAMESPACE::x86; - if(size == 0) return; - if(size == 1) return splat_set<_1>(dst, value); - if(size < 4) return splat_set>(dst, value, size); - if(size < 8) return splat_set>(dst, value, size); - if(size < 16) return splat_set>(dst, value, size); - if(size < 32) return splat_set>(dst, value, size); - if(size < 64) return splat_set>(dst, value, size); - if(size < 128) return splat_set>(dst, value, size); - if(size < 256) return splat_set>(dst, value, size); - return splat_set::Then>>(dst, value, size); -} -static void bzero_0x475977492C218AD4(char * dst, size_t size) { - using namespace LIBC_NAMESPACE::x86; - if(size == 0) return; - if(size == 1) return splat_set<_1>(dst, 0); - if(size == 2) return splat_set<_2>(dst, 0); - if(size == 3) return splat_set<_3>(dst, 0); - if(size < 8) return splat_set>(dst, 0, size); - if(size < 16) return splat_set>(dst, 0, size); - if(size < 32) return splat_set>(dst, 0, size); - if(size < 64) return splat_set>(dst, 0, size); - if(size < 128) return splat_set>(dst, 0, size); - return splat_set::Then>>(dst, 0, size); -} - -} // namespace LIBC_NAMESPACE_DECL - -namespace llvm { -namespace automemcpy { - -ArrayRef getFunctionDescriptors() { - static constexpr NamedFunctionDescriptor kDescriptors[] = { - {"memcpy_0xE00E29EE73994E2B",{FunctionType::MEMCPY,std::nullopt,std::nullopt,std::nullopt,std::nullopt,Accelerator{{0,kMaxSize}},ElementTypeClass::NATIVE}}, - {"memcpy_0x7381B60C7BE75EF9",{FunctionType::MEMCPY,Contiguous{{0,4}},Overlap{{4,256}},Loop{{256,kMaxSize},64},std::nullopt,std::nullopt,ElementTypeClass::NATIVE}}, - {"memcmp_0x348D7BA6DB0EE033",{FunctionType::MEMCMP,Contiguous{{0,2}},Overlap{{2,64}},std::nullopt,AlignedLoop{Loop{{64,kMaxSize},16},16,AlignArg::_1},std::nullopt,ElementTypeClass::NATIVE}}, - {"memset_0x71E761699B999863",{FunctionType::MEMSET,Contiguous{{0,2}},Overlap{{2,256}},std::nullopt,AlignedLoop{Loop{{256,kMaxSize},32},16,AlignArg::_1},std::nullopt,ElementTypeClass::NATIVE}}, - {"memset_0x3DF0F44E2ED6A50F",{FunctionType::MEMSET,Contiguous{{0,2}},Overlap{{2,256}},std::nullopt,AlignedLoop{Loop{{256,kMaxSize},32},32,AlignArg::_1},std::nullopt,ElementTypeClass::NATIVE}}, - {"bzero_0x475977492C218AD4",{FunctionType::BZERO,Contiguous{{0,4}},Overlap{{4,128}},std::nullopt,AlignedLoop{Loop{{128,kMaxSize},32},32,AlignArg::_1},std::nullopt,ElementTypeClass::NATIVE}}, - }; - return ArrayRef(kDescriptors); -} - -} // namespace automemcpy -} // namespace llvm - - -using MemcpyStub = void (*)(char *__restrict, const char *__restrict, size_t); -template -void *Wrap(void *__restrict dst, const void *__restrict src, size_t size) { - Foo(reinterpret_cast(dst), - reinterpret_cast(src), size); - return dst; -} -llvm::ArrayRef getMemcpyConfigurations() { - using namespace LIBC_NAMESPACE; - static constexpr MemcpyConfiguration kConfigurations[] = { - {Wrap, "memcpy_0xE00E29EE73994E2B"}, - {Wrap, "memcpy_0x7381B60C7BE75EF9"}, - }; - return llvm::ArrayRef(kConfigurations); -} - -using MemcmpStub = int (*)(const char *, const char *, size_t); -template -int Wrap(const void *lhs, const void *rhs, size_t size) { - return Foo(reinterpret_cast(lhs), - reinterpret_cast(rhs), size); -} -llvm::ArrayRef getMemcmpConfigurations() { - using namespace LIBC_NAMESPACE; - static constexpr MemcmpOrBcmpConfiguration kConfigurations[] = { - {Wrap, "memcmp_0x348D7BA6DB0EE033"}, - }; - return llvm::ArrayRef(kConfigurations); -} -llvm::ArrayRef getBcmpConfigurations() { - return {}; -} - -using MemsetStub = void (*)(char *, int, size_t); -template void *Wrap(void *dst, int value, size_t size) { - Foo(reinterpret_cast(dst), value, size); - return dst; -} -llvm::ArrayRef getMemsetConfigurations() { - using namespace LIBC_NAMESPACE; - static constexpr MemsetConfiguration kConfigurations[] = { - {Wrap, "memset_0x71E761699B999863"}, - {Wrap, "memset_0x3DF0F44E2ED6A50F"}, - }; - return llvm::ArrayRef(kConfigurations); -} - -using BzeroStub = void (*)(char *, size_t); -template void Wrap(void *dst, size_t size) { - Foo(reinterpret_cast(dst), size); -} -llvm::ArrayRef getBzeroConfigurations() { - using namespace LIBC_NAMESPACE; - static constexpr BzeroConfiguration kConfigurations[] = { - {Wrap, "bzero_0x475977492C218AD4"}, - }; - return llvm::ArrayRef(kConfigurations); -} - -llvm::ArrayRef getMemmoveConfigurations() { - return {}; -} -// Functions : 6 -)"); -} -} // namespace -} // namespace automemcpy -} // namespace llvm diff --git a/libc/benchmarks/automemcpy/unittests/ResultAnalyzerTest.cpp b/libc/benchmarks/automemcpy/unittests/ResultAnalyzerTest.cpp deleted file mode 100644 index 7b67f70eb89cd..0000000000000 --- a/libc/benchmarks/automemcpy/unittests/ResultAnalyzerTest.cpp +++ /dev/null @@ -1,191 +0,0 @@ -//===-- Automemcpy Json Results Analyzer Test ----------------------------===// -// -// 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 "automemcpy/ResultAnalyzer.h" -#include "gmock/gmock.h" -#include "gtest/gtest.h" - -using testing::DoubleNear; -using testing::ElementsAre; -using testing::Pair; -using testing::SizeIs; - -namespace llvm { -namespace automemcpy { -namespace { - -TEST(AutomemcpyJsonResultsAnalyzer, getThroughputsOneSample) { - static constexpr FunctionId Foo1 = {"memcpy1", FunctionType::MEMCPY}; - static constexpr DistributionId DistA = {{"A"}}; - static constexpr SampleId Id = {Foo1, DistA}; - static constexpr Sample kSamples[] = { - Sample{Id, SampleType::ITERATION, 4}, - Sample{Id, SampleType::AGGREGATE, -1}, // Aggegates gets discarded - }; - - const std::vector Data = getThroughputs(kSamples); - EXPECT_THAT(Data, SizeIs(1)); - EXPECT_THAT(Data[0].Id, Foo1); - EXPECT_THAT(Data[0].PerDistributionData, SizeIs(1)); - // A single value is provided. - const auto &DistributionData = Data[0].PerDistributionData.lookup(DistA.Name); - EXPECT_THAT(DistributionData.BytesPerSecondMedian, 4); - EXPECT_THAT(DistributionData.BytesPerSecondMean, 4); - EXPECT_THAT(DistributionData.BytesPerSecondVariance, 0); -} - -TEST(AutomemcpyJsonResultsAnalyzer, getThroughputsManySamplesSameBucket) { - static constexpr FunctionId Foo1 = {"memcpy1", FunctionType::MEMCPY}; - static constexpr DistributionId DistA = {{"A"}}; - static constexpr SampleId Id = {Foo1, DistA}; - static constexpr Sample kSamples[] = {Sample{Id, SampleType::ITERATION, 4}, - Sample{Id, SampleType::ITERATION, 5}, - Sample{Id, SampleType::ITERATION, 5}}; - - const std::vector Data = getThroughputs(kSamples); - EXPECT_THAT(Data, SizeIs(1)); - EXPECT_THAT(Data[0].Id, Foo1); - EXPECT_THAT(Data[0].PerDistributionData, SizeIs(1)); - // When multiple values are provided we pick the median one (here median of 4, - // 5, 5). - const auto &DistributionData = Data[0].PerDistributionData.lookup(DistA.Name); - EXPECT_THAT(DistributionData.BytesPerSecondMedian, 5); - EXPECT_THAT(DistributionData.BytesPerSecondMean, DoubleNear(4.6, 0.1)); - EXPECT_THAT(DistributionData.BytesPerSecondVariance, DoubleNear(0.33, 0.01)); -} - -TEST(AutomemcpyJsonResultsAnalyzer, getThroughputsServeralFunctionAndDist) { - static constexpr FunctionId Foo1 = {"memcpy1", FunctionType::MEMCPY}; - static constexpr DistributionId DistA = {{"A"}}; - static constexpr FunctionId Foo2 = {"memcpy2", FunctionType::MEMCPY}; - static constexpr DistributionId DistB = {{"B"}}; - static constexpr Sample kSamples[] = { - Sample{{Foo1, DistA}, SampleType::ITERATION, 1}, - Sample{{Foo1, DistB}, SampleType::ITERATION, 2}, - Sample{{Foo2, DistA}, SampleType::ITERATION, 3}, - Sample{{Foo2, DistB}, SampleType::ITERATION, 4}}; - // Data is aggregated per function. - const std::vector Data = getThroughputs(kSamples); - EXPECT_THAT(Data, SizeIs(2)); // 2 functions Foo1 and Foo2. - // Each function has data for both distributions DistA and DistB. - EXPECT_THAT(Data[0].PerDistributionData, SizeIs(2)); - EXPECT_THAT(Data[1].PerDistributionData, SizeIs(2)); -} - -TEST(AutomemcpyJsonResultsAnalyzer, getScore) { - static constexpr FunctionId Foo1 = {"memcpy1", FunctionType::MEMCPY}; - static constexpr FunctionId Foo2 = {"memcpy2", FunctionType::MEMCPY}; - static constexpr FunctionId Foo3 = {"memcpy3", FunctionType::MEMCPY}; - static constexpr DistributionId Dist = {{"A"}}; - static constexpr Sample kSamples[] = { - Sample{{Foo1, Dist}, SampleType::ITERATION, 1}, - Sample{{Foo2, Dist}, SampleType::ITERATION, 2}, - Sample{{Foo3, Dist}, SampleType::ITERATION, 3}}; - - // Data is aggregated per function. - std::vector Data = getThroughputs(kSamples); - - // Sort Data by function name so we can test them. - std::sort( - Data.begin(), Data.end(), - [](const FunctionData &A, const FunctionData &B) { return A.Id < B.Id; }); - - EXPECT_THAT(Data[0].Id, Foo1); - EXPECT_THAT(Data[0].PerDistributionData.lookup("A").BytesPerSecondMedian, 1); - EXPECT_THAT(Data[1].Id, Foo2); - EXPECT_THAT(Data[1].PerDistributionData.lookup("A").BytesPerSecondMedian, 2); - EXPECT_THAT(Data[2].Id, Foo3); - EXPECT_THAT(Data[2].PerDistributionData.lookup("A").BytesPerSecondMedian, 3); - - // Normalizes throughput per distribution. - fillScores(Data); - EXPECT_THAT(Data[0].PerDistributionData.lookup("A").Score, 0); - EXPECT_THAT(Data[1].PerDistributionData.lookup("A").Score, 0.5); - EXPECT_THAT(Data[2].PerDistributionData.lookup("A").Score, 1); -} - -TEST(AutomemcpyJsonResultsAnalyzer, castVotes) { - static constexpr double kAbsErr = 0.01; - - static constexpr FunctionId Foo1 = {"memcpy1", FunctionType::MEMCPY}; - static constexpr FunctionId Foo2 = {"memcpy2", FunctionType::MEMCPY}; - static constexpr FunctionId Foo3 = {"memcpy3", FunctionType::MEMCPY}; - static constexpr DistributionId DistA = {{"A"}}; - static constexpr DistributionId DistB = {{"B"}}; - static constexpr Sample kSamples[] = { - Sample{{Foo1, DistA}, SampleType::ITERATION, 0}, - Sample{{Foo1, DistB}, SampleType::ITERATION, 30}, - Sample{{Foo2, DistA}, SampleType::ITERATION, 1}, - Sample{{Foo2, DistB}, SampleType::ITERATION, 100}, - Sample{{Foo3, DistA}, SampleType::ITERATION, 7}, - Sample{{Foo3, DistB}, SampleType::ITERATION, 100}, - }; - - // DistA Thoughput ranges from 0 to 7. - // DistB Thoughput ranges from 30 to 100. - - // Data is aggregated per function. - std::vector Data = getThroughputs(kSamples); - - // Sort Data by function name so we can test them. - std::sort( - Data.begin(), Data.end(), - [](const FunctionData &A, const FunctionData &B) { return A.Id < B.Id; }); - - // Normalizes throughput per distribution. - fillScores(Data); - - // Cast votes - castVotes(Data); - - EXPECT_THAT(Data[0].Id, Foo1); - EXPECT_THAT(Data[1].Id, Foo2); - EXPECT_THAT(Data[2].Id, Foo3); - - const auto GetDistData = [&Data](size_t Index, StringRef Name) { - return Data[Index].PerDistributionData.lookup(Name); - }; - - // Distribution A - // Throughput is 0, 1 and 7, so normalized scores are 0, 1/7 and 1. - EXPECT_THAT(GetDistData(0, "A").Score, DoubleNear(0, kAbsErr)); - EXPECT_THAT(GetDistData(1, "A").Score, DoubleNear(1. / 7, kAbsErr)); - EXPECT_THAT(GetDistData(2, "A").Score, DoubleNear(1, kAbsErr)); - // which are turned into grades BAD, MEDIOCRE and EXCELLENT. - EXPECT_THAT(GetDistData(0, "A").Grade, Grade::BAD); - EXPECT_THAT(GetDistData(1, "A").Grade, Grade::MEDIOCRE); - EXPECT_THAT(GetDistData(2, "A").Grade, Grade::EXCELLENT); - - // Distribution B - // Throughput is 30, 100 and 100, so normalized scores are 0, 1 and 1. - EXPECT_THAT(GetDistData(0, "B").Score, DoubleNear(0, kAbsErr)); - EXPECT_THAT(GetDistData(1, "B").Score, DoubleNear(1, kAbsErr)); - EXPECT_THAT(GetDistData(2, "B").Score, DoubleNear(1, kAbsErr)); - // which are turned into grades BAD, EXCELLENT and EXCELLENT. - EXPECT_THAT(GetDistData(0, "B").Grade, Grade::BAD); - EXPECT_THAT(GetDistData(1, "B").Grade, Grade::EXCELLENT); - EXPECT_THAT(GetDistData(2, "B").Grade, Grade::EXCELLENT); - - // Now looking from the functions point of view. - EXPECT_THAT(Data[0].ScoresGeoMean, DoubleNear(0, kAbsErr)); - EXPECT_THAT(Data[1].ScoresGeoMean, DoubleNear(1. * (1. / 7), kAbsErr)); - EXPECT_THAT(Data[2].ScoresGeoMean, DoubleNear(1, kAbsErr)); - - // Note the array is indexed by GradeEnum values (EXCELLENT=0 / BAD = 6) - EXPECT_THAT(Data[0].GradeHisto, ElementsAre(0, 0, 0, 0, 0, 0, 2)); - EXPECT_THAT(Data[1].GradeHisto, ElementsAre(1, 0, 0, 0, 0, 1, 0)); - EXPECT_THAT(Data[2].GradeHisto, ElementsAre(2, 0, 0, 0, 0, 0, 0)); - - EXPECT_THAT(Data[0].FinalGrade, Grade::BAD); - EXPECT_THAT(Data[1].FinalGrade, Grade::MEDIOCRE); - EXPECT_THAT(Data[2].FinalGrade, Grade::EXCELLENT); -} - -} // namespace -} // namespace automemcpy -} // namespace llvm diff --git a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake index 65851f1c86571..8dcee1ec42246 100644 --- a/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake +++ b/libc/cmake/modules/LLVMLibCCompileOptionRules.cmake @@ -1,3 +1,15 @@ +if(NOT DEFINED LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE) + if(CMAKE_COMPILER_IS_GNUCXX) + set(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE ON) + elseif( MSVC ) + set(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE OFF) + elseif( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" ) + set(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE ON) + elseif( "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel" ) + set(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE ON) + endif() +endif() + function(_get_compile_options_from_flags output_var) set(compile_options "") @@ -8,7 +20,7 @@ function(_get_compile_options_from_flags output_var) check_flag(ADD_EXPLICIT_SIMD_OPT_FLAG ${EXPLICIT_SIMD_OPT_FLAG} ${ARGN}) check_flag(ADD_MISC_MATH_BASIC_OPS_OPT_FLAG ${MISC_MATH_BASIC_OPS_OPT_FLAG} ${ARGN}) - if(LLVM_COMPILER_IS_GCC_COMPATIBLE) + if(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE) if(ADD_FMA_FLAG) if(LIBC_TARGET_ARCHITECTURE_IS_X86_64) list(APPEND compile_options "-mavx2") @@ -96,7 +108,7 @@ function(_get_common_compile_options output_var flags) set(compile_options ${LIBC_COMPILE_OPTIONS_DEFAULT} ${compile_flags} ${config_flags}) - if(LLVM_COMPILER_IS_GCC_COMPATIBLE) + if(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE) list(APPEND compile_options "-fpie") if(LLVM_LIBC_FULL_BUILD) @@ -210,7 +222,7 @@ function(_get_common_test_compile_options output_var c_test flags) ${LIBC_TEST_COMPILE_OPTIONS_DEFAULT} ${compile_flags}) - if(LLVM_COMPILER_IS_GCC_COMPATIBLE) + if(LLVM_LIBC_COMPILER_IS_GCC_COMPATIBLE) list(APPEND compile_options "-fpie") if(LLVM_LIBC_FULL_BUILD) diff --git a/libc/cmake/modules/LLVMLibCObjectRules.cmake b/libc/cmake/modules/LLVMLibCObjectRules.cmake index 68b5ed1ed51c0..142778d9ea1cc 100644 --- a/libc/cmake/modules/LLVMLibCObjectRules.cmake +++ b/libc/cmake/modules/LLVMLibCObjectRules.cmake @@ -452,3 +452,41 @@ function(add_redirector_object target_name) BEFORE PRIVATE -fPIC ${LIBC_COMPILE_OPTIONS_DEFAULT} ) endfunction(add_redirector_object) + +# Helper to define a function with multiple implementations +# - Computes flags to satisfy required/rejected features and arch, +# - Declares an entry point, +# - Attach the REQUIRE_CPU_FEATURES property to the target, +# - Add the fully qualified target to `${name}_implementations` global property for tests. +function(add_implementation name impl_name) + cmake_parse_arguments( + "ADD_IMPL" + "" # Optional arguments + "" # Single value arguments + "REQUIRE;SRCS;HDRS;DEPENDS;COMPILE_OPTIONS;MLLVM_COMPILE_OPTIONS" # Multi value arguments + ${ARGN}) + + if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") + # Note that '-mllvm' needs to be prefixed with 'SHELL:' to prevent CMake flag deduplication. + foreach(opt IN LISTS ADD_IMPL_MLLVM_COMPILE_OPTIONS) + list(APPEND ADD_IMPL_COMPILE_OPTIONS "SHELL:-mllvm ${opt}") + endforeach() + endif() + + if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") + # Prevent warning when passing x86 SIMD types as template arguments. + # e.g. "warning: ignoring attributes on template argument ‘__m128i’ [-Wignored-attributes]" + list(APPEND ADD_IMPL_COMPILE_OPTIONS "-Wno-ignored-attributes") + endif() + + add_entrypoint_object(${impl_name} + NAME ${name} + SRCS ${ADD_IMPL_SRCS} + HDRS ${ADD_IMPL_HDRS} + DEPENDS ${ADD_IMPL_DEPENDS} + COMPILE_OPTIONS ${libc_opt_high_flag} ${ADD_IMPL_COMPILE_OPTIONS} + ) + get_fq_target_name(${impl_name} fq_target_name) + set_target_properties(${fq_target_name} PROPERTIES REQUIRE_CPU_FEATURES "${ADD_IMPL_REQUIRE}") + set_property(GLOBAL APPEND PROPERTY "${name}_implementations" "${fq_target_name}") +endfunction() diff --git a/libc/cmake/modules/LLVMLibCTestRules.cmake b/libc/cmake/modules/LLVMLibCTestRules.cmake index 36f871920c3c3..84f3125d557ea 100644 --- a/libc/cmake/modules/LLVMLibCTestRules.cmake +++ b/libc/cmake/modules/LLVMLibCTestRules.cmake @@ -416,12 +416,12 @@ function(add_integration_test test_name) libc.test.IntegrationTest.test # We always add the memory functions objects. This is because the # compiler's codegen can emit calls to the C memory functions. - libc.src.string.bcmp - libc.src.string.bzero libc.src.string.memcmp libc.src.string.memcpy libc.src.string.memmove libc.src.string.memset + libc.src.strings.bcmp + libc.src.strings.bzero ) if(libc.src.compiler.__stack_chk_fail IN_LIST TARGET_LLVMLIBC_ENTRYPOINTS) @@ -583,13 +583,13 @@ function(add_libc_hermetic test_name) libc.startup.${LIBC_TARGET_OS}.crt1 # We always add the memory functions objects. This is because the # compiler's codegen can emit calls to the C memory functions. - libc.src.string.bcmp - libc.src.string.bzero + libc.src.__support.StringUtil.error_to_string libc.src.string.memcmp libc.src.string.memcpy libc.src.string.memmove libc.src.string.memset - libc.src.__support.StringUtil.error_to_string + libc.src.strings.bcmp + libc.src.strings.bzero ) if(libc.src.compiler.__stack_chk_fail IN_LIST TARGET_LLVMLIBC_ENTRYPOINTS) @@ -766,3 +766,33 @@ function(add_libc_test test_name) endif() endif() endfunction(add_libc_test) + +# Tests all implementations that can run on the target CPU. +function(add_libc_multi_impl_test name suite) + get_property(fq_implementations GLOBAL PROPERTY ${name}_implementations) + foreach(fq_config_name IN LISTS fq_implementations) + get_target_property(required_cpu_features ${fq_config_name} REQUIRE_CPU_FEATURES) + cpu_supports(can_run "${required_cpu_features}") + if(can_run) + string(FIND ${fq_config_name} "." last_dot_loc REVERSE) + math(EXPR name_loc "${last_dot_loc} + 1") + string(SUBSTRING ${fq_config_name} ${name_loc} -1 target_name) + add_libc_test( + ${target_name}_test + SUITE + ${suite} + COMPILE_OPTIONS + ${LIBC_COMPILE_OPTIONS_NATIVE} + LINK_LIBRARIES + LibcMemoryHelpers + ${ARGN} + DEPENDS + ${fq_config_name} + libc.src.__support.macros.sanitizer + ) + get_fq_target_name(${fq_config_name}_test fq_target_name) + else() + message(STATUS "Skipping test for '${fq_config_name}' insufficient host cpu features '${required_cpu_features}'") + endif() + endforeach() +endfunction() diff --git a/libc/config/baremetal/aarch64/entrypoints.txt b/libc/config/baremetal/aarch64/entrypoints.txt new file mode 100644 index 0000000000000..694cd7b1993ca --- /dev/null +++ b/libc/config/baremetal/aarch64/entrypoints.txt @@ -0,0 +1,478 @@ +set(TARGET_LIBC_ENTRYPOINTS + # assert.h entrypoints + libc.src.assert.__assert_fail + + # ctype.h entrypoints + libc.src.ctype.isalnum + libc.src.ctype.isalpha + libc.src.ctype.isascii + libc.src.ctype.isblank + libc.src.ctype.iscntrl + libc.src.ctype.isdigit + libc.src.ctype.isgraph + libc.src.ctype.islower + libc.src.ctype.isprint + libc.src.ctype.ispunct + libc.src.ctype.isspace + libc.src.ctype.isupper + libc.src.ctype.isxdigit + libc.src.ctype.toascii + libc.src.ctype.tolower + libc.src.ctype.toupper + + # compiler entrypoints (no corresponding header) + libc.src.compiler.__stack_chk_fail + + # errno.h entrypoints + libc.src.errno.errno + + # setjmp.h entrypoints + libc.src.setjmp.longjmp + libc.src.setjmp.setjmp + + # string.h entrypoints + libc.src.string.memccpy + libc.src.string.memchr + libc.src.string.memcmp + libc.src.string.memcpy + libc.src.string.memmem + libc.src.string.memmove + libc.src.string.mempcpy + libc.src.string.memrchr + libc.src.string.memset + libc.src.string.memset_explicit + libc.src.string.stpcpy + libc.src.string.stpncpy + libc.src.string.strcasestr + libc.src.string.strcat + libc.src.string.strchr + libc.src.string.strchrnul + libc.src.string.strcmp + libc.src.string.strcoll + libc.src.string.strcpy + libc.src.string.strcspn + libc.src.string.strerror + libc.src.string.strerror_r + libc.src.string.strlcat + libc.src.string.strlcpy + libc.src.string.strlen + libc.src.string.strncat + libc.src.string.strncmp + libc.src.string.strncpy + libc.src.string.strnlen + libc.src.string.strpbrk + libc.src.string.strrchr + libc.src.string.strsep + libc.src.string.strspn + libc.src.string.strstr + libc.src.string.strtok + libc.src.string.strtok_r + libc.src.string.strxfrm + + # strings.h entrypoints + libc.src.strings.bcmp + libc.src.strings.bcopy + libc.src.strings.bzero + libc.src.strings.index + libc.src.strings.rindex + libc.src.strings.strcasecmp + libc.src.strings.strncasecmp + + # inttypes.h entrypoints + libc.src.inttypes.imaxabs + libc.src.inttypes.imaxdiv + libc.src.inttypes.strtoimax + libc.src.inttypes.strtoumax + + # stdio.h entrypoints + libc.src.stdio.getchar + libc.src.stdio.printf + libc.src.stdio.putchar + libc.src.stdio.puts + libc.src.stdio.remove + libc.src.stdio.snprintf + libc.src.stdio.sprintf + libc.src.stdio.asprintf + libc.src.stdio.vprintf + libc.src.stdio.vsnprintf + libc.src.stdio.vsprintf + libc.src.stdio.vasprintf + + # stdbit.h entrypoints + libc.src.stdbit.stdc_bit_ceil_uc + libc.src.stdbit.stdc_bit_ceil_ui + libc.src.stdbit.stdc_bit_ceil_ul + libc.src.stdbit.stdc_bit_ceil_ull + libc.src.stdbit.stdc_bit_ceil_us + libc.src.stdbit.stdc_bit_floor_uc + libc.src.stdbit.stdc_bit_floor_ui + libc.src.stdbit.stdc_bit_floor_ul + libc.src.stdbit.stdc_bit_floor_ull + libc.src.stdbit.stdc_bit_floor_us + libc.src.stdbit.stdc_bit_width_uc + libc.src.stdbit.stdc_bit_width_ui + libc.src.stdbit.stdc_bit_width_ul + libc.src.stdbit.stdc_bit_width_ull + libc.src.stdbit.stdc_bit_width_us + libc.src.stdbit.stdc_count_ones_uc + libc.src.stdbit.stdc_count_ones_ui + libc.src.stdbit.stdc_count_ones_ul + libc.src.stdbit.stdc_count_ones_ull + libc.src.stdbit.stdc_count_ones_us + libc.src.stdbit.stdc_count_zeros_uc + libc.src.stdbit.stdc_count_zeros_ui + libc.src.stdbit.stdc_count_zeros_ul + libc.src.stdbit.stdc_count_zeros_ull + libc.src.stdbit.stdc_count_zeros_us + libc.src.stdbit.stdc_first_leading_one_uc + libc.src.stdbit.stdc_first_leading_one_ui + libc.src.stdbit.stdc_first_leading_one_ul + libc.src.stdbit.stdc_first_leading_one_ull + libc.src.stdbit.stdc_first_leading_one_us + libc.src.stdbit.stdc_first_leading_zero_uc + libc.src.stdbit.stdc_first_leading_zero_ui + libc.src.stdbit.stdc_first_leading_zero_ul + libc.src.stdbit.stdc_first_leading_zero_ull + libc.src.stdbit.stdc_first_leading_zero_us + libc.src.stdbit.stdc_first_trailing_one_uc + libc.src.stdbit.stdc_first_trailing_one_ui + libc.src.stdbit.stdc_first_trailing_one_ul + libc.src.stdbit.stdc_first_trailing_one_ull + libc.src.stdbit.stdc_first_trailing_one_us + libc.src.stdbit.stdc_first_trailing_zero_uc + libc.src.stdbit.stdc_first_trailing_zero_ui + libc.src.stdbit.stdc_first_trailing_zero_ul + libc.src.stdbit.stdc_first_trailing_zero_ull + libc.src.stdbit.stdc_first_trailing_zero_us + libc.src.stdbit.stdc_has_single_bit_uc + libc.src.stdbit.stdc_has_single_bit_ui + libc.src.stdbit.stdc_has_single_bit_ul + libc.src.stdbit.stdc_has_single_bit_ull + libc.src.stdbit.stdc_has_single_bit_us + libc.src.stdbit.stdc_leading_ones_uc + libc.src.stdbit.stdc_leading_ones_ui + libc.src.stdbit.stdc_leading_ones_ul + libc.src.stdbit.stdc_leading_ones_ull + libc.src.stdbit.stdc_leading_ones_us + libc.src.stdbit.stdc_leading_zeros_uc + libc.src.stdbit.stdc_leading_zeros_ui + libc.src.stdbit.stdc_leading_zeros_ul + libc.src.stdbit.stdc_leading_zeros_ull + libc.src.stdbit.stdc_leading_zeros_us + libc.src.stdbit.stdc_trailing_ones_uc + libc.src.stdbit.stdc_trailing_ones_ui + libc.src.stdbit.stdc_trailing_ones_ul + libc.src.stdbit.stdc_trailing_ones_ull + libc.src.stdbit.stdc_trailing_ones_us + libc.src.stdbit.stdc_trailing_zeros_uc + libc.src.stdbit.stdc_trailing_zeros_ui + libc.src.stdbit.stdc_trailing_zeros_ul + libc.src.stdbit.stdc_trailing_zeros_ull + libc.src.stdbit.stdc_trailing_zeros_us + + # stdlib.h entrypoints + libc.src.stdlib._Exit + libc.src.stdlib.abort + libc.src.stdlib.abs + libc.src.stdlib.aligned_alloc + libc.src.stdlib.atof + libc.src.stdlib.atoi + libc.src.stdlib.atol + libc.src.stdlib.atoll + libc.src.stdlib.bsearch + libc.src.stdlib.calloc + libc.src.stdlib.div + libc.src.stdlib.exit + libc.src.stdlib.free + libc.src.stdlib.labs + libc.src.stdlib.ldiv + libc.src.stdlib.llabs + libc.src.stdlib.lldiv + libc.src.stdlib.malloc + libc.src.stdlib.qsort + libc.src.stdlib.rand + libc.src.stdlib.realloc + libc.src.stdlib.srand + libc.src.stdlib.strtod + libc.src.stdlib.strtof + libc.src.stdlib.strtol + libc.src.stdlib.strtold + libc.src.stdlib.strtoll + libc.src.stdlib.strtoul + libc.src.stdlib.strtoull + + # time.h entrypoints + libc.src.time.asctime + libc.src.time.asctime_r + libc.src.time.ctime + libc.src.time.ctime_r + libc.src.time.difftime + libc.src.time.gmtime + libc.src.time.gmtime_r + libc.src.time.mktime + libc.src.time.timespec_get + + # internal entrypoints + libc.startup.baremetal.init + libc.startup.baremetal.fini +) + +set(TARGET_LIBM_ENTRYPOINTS + # fenv.h entrypoints + libc.src.fenv.feclearexcept + libc.src.fenv.fedisableexcept + libc.src.fenv.feenableexcept + libc.src.fenv.fegetenv + libc.src.fenv.fegetexcept + libc.src.fenv.fegetexceptflag + libc.src.fenv.fegetround + libc.src.fenv.feholdexcept + libc.src.fenv.feraiseexcept + libc.src.fenv.fesetenv + libc.src.fenv.fesetexcept + libc.src.fenv.fesetexceptflag + libc.src.fenv.fesetround + libc.src.fenv.fetestexcept + libc.src.fenv.fetestexceptflag + libc.src.fenv.feupdateenv + + # math.h entrypoints + libc.src.math.acosf + libc.src.math.acoshf + libc.src.math.asinf + libc.src.math.asinhf + libc.src.math.atan2 + libc.src.math.atan2f + libc.src.math.atanf + libc.src.math.atanhf + libc.src.math.canonicalize + libc.src.math.canonicalizef + libc.src.math.canonicalizel + libc.src.math.cbrt + libc.src.math.cbrtf + libc.src.math.ceil + libc.src.math.ceilf + libc.src.math.ceill + libc.src.math.copysign + libc.src.math.copysignf + libc.src.math.copysignl + libc.src.math.cos + libc.src.math.cosf + libc.src.math.coshf + libc.src.math.erff + libc.src.math.exp + libc.src.math.exp10 + libc.src.math.exp10f + libc.src.math.exp2 + libc.src.math.exp2f + libc.src.math.exp2m1f + libc.src.math.expf + libc.src.math.expm1 + libc.src.math.expm1f + libc.src.math.fabs + libc.src.math.fabsf + libc.src.math.fabsl + libc.src.math.fdim + libc.src.math.fdimf + libc.src.math.fdiml + libc.src.math.floor + libc.src.math.floorf + libc.src.math.floorl + libc.src.math.fma + libc.src.math.fmaf + libc.src.math.fmax + libc.src.math.fmaxf + libc.src.math.fmaximum + libc.src.math.fmaximum_mag + libc.src.math.fmaximum_mag_num + libc.src.math.fmaximum_mag_numf + libc.src.math.fmaximum_mag_numl + libc.src.math.fmaximum_magf + libc.src.math.fmaximum_magl + libc.src.math.fmaximum_num + libc.src.math.fmaximum_numf + libc.src.math.fmaximum_numl + libc.src.math.fmaximumf + libc.src.math.fmaximuml + libc.src.math.fmaxl + libc.src.math.fmin + libc.src.math.fminf + libc.src.math.fminimum + libc.src.math.fminimum_mag + libc.src.math.fminimum_mag_num + libc.src.math.fminimum_mag_numf + libc.src.math.fminimum_mag_numl + libc.src.math.fminimum_magf + libc.src.math.fminimum_magl + libc.src.math.fminimum_num + libc.src.math.fminimum_numf + libc.src.math.fminimum_numl + libc.src.math.fminimumf + libc.src.math.fminimuml + libc.src.math.fminl + libc.src.math.fmod + libc.src.math.fmodf + libc.src.math.fmodl + libc.src.math.fmul + libc.src.math.frexp + libc.src.math.frexpf + libc.src.math.frexpl + libc.src.math.fromfp + libc.src.math.fromfpf + libc.src.math.fromfpl + libc.src.math.fromfpx + libc.src.math.fromfpxf + libc.src.math.fromfpxl + libc.src.math.hypot + libc.src.math.hypotf + libc.src.math.ilogb + libc.src.math.ilogbf + libc.src.math.ilogbl + libc.src.math.isnan + libc.src.math.isnanf + libc.src.math.isnanl + libc.src.math.ldexp + libc.src.math.ldexpf + libc.src.math.ldexpl + libc.src.math.llogb + libc.src.math.llogbf + libc.src.math.llogbl + libc.src.math.llrint + libc.src.math.llrintf + libc.src.math.llrintl + libc.src.math.llround + libc.src.math.llroundf + libc.src.math.llroundl + libc.src.math.log + libc.src.math.log10 + libc.src.math.log10f + libc.src.math.log1p + libc.src.math.log1pf + libc.src.math.log2 + libc.src.math.log2f + libc.src.math.logb + libc.src.math.logbf + libc.src.math.logbl + libc.src.math.logf + libc.src.math.lrint + libc.src.math.lrintf + libc.src.math.lrintl + libc.src.math.lround + libc.src.math.lroundf + libc.src.math.lroundl + libc.src.math.modf + libc.src.math.modff + libc.src.math.modfl + libc.src.math.nan + libc.src.math.nanf + libc.src.math.nanl + libc.src.math.nearbyint + libc.src.math.nearbyintf + libc.src.math.nearbyintl + libc.src.math.nextafter + libc.src.math.nextafterf + libc.src.math.nextafterl + libc.src.math.nextdown + libc.src.math.nextdownf + libc.src.math.nextdownl + libc.src.math.nexttoward + libc.src.math.nexttowardf + libc.src.math.nexttowardl + libc.src.math.nextup + libc.src.math.nextupf + libc.src.math.nextupl + libc.src.math.pow + libc.src.math.powf + libc.src.math.remainder + libc.src.math.remainderf + libc.src.math.remainderl + libc.src.math.remquo + libc.src.math.remquof + libc.src.math.remquol + libc.src.math.rint + libc.src.math.rintf + libc.src.math.rintl + libc.src.math.round + libc.src.math.roundeven + libc.src.math.roundevenf + libc.src.math.roundevenl + libc.src.math.roundf + libc.src.math.roundl + libc.src.math.scalbln + libc.src.math.scalblnf + libc.src.math.scalblnl + libc.src.math.scalbn + libc.src.math.scalbnf + libc.src.math.scalbnl + libc.src.math.sin + libc.src.math.sincos + libc.src.math.sincosf + libc.src.math.sinf + libc.src.math.sinhf + libc.src.math.sqrt + libc.src.math.sqrtf + libc.src.math.sqrtl + libc.src.math.tan + libc.src.math.tanf + libc.src.math.tanhf + libc.src.math.trunc + libc.src.math.truncf + libc.src.math.truncl + libc.src.math.ufromfp + libc.src.math.ufromfpf + libc.src.math.ufromfpl + libc.src.math.ufromfpx + libc.src.math.ufromfpxf + libc.src.math.ufromfpxl +) + +if(LIBC_COMPILER_HAS_FIXED_POINT) + list(APPEND TARGET_LIBM_ENTRYPOINTS + # stdfix.h _Fract and _Accum entrypoints + libc.src.stdfix.abshk + libc.src.stdfix.abshr + libc.src.stdfix.absk + libc.src.stdfix.abslk + libc.src.stdfix.abslr + libc.src.stdfix.absr + libc.src.stdfix.exphk + libc.src.stdfix.expk + libc.src.stdfix.roundhk + libc.src.stdfix.roundhr + libc.src.stdfix.roundk + libc.src.stdfix.roundlk + libc.src.stdfix.roundlr + libc.src.stdfix.roundr + libc.src.stdfix.rounduhk + libc.src.stdfix.rounduhr + libc.src.stdfix.rounduk + libc.src.stdfix.roundulk + libc.src.stdfix.roundulr + libc.src.stdfix.roundur + libc.src.stdfix.sqrtuhk + libc.src.stdfix.sqrtuhr + libc.src.stdfix.sqrtuk + libc.src.stdfix.sqrtur + # libc.src.stdfix.sqrtulk + libc.src.stdfix.sqrtulr + libc.src.stdfix.uhksqrtus + libc.src.stdfix.uksqrtui + libc.src.stdfix.hrbits + libc.src.stdfix.uhrbits + libc.src.stdfix.rbits + libc.src.stdfix.urbits + libc.src.stdfix.lrbits + libc.src.stdfix.ulrbits + libc.src.stdfix.hkbits + libc.src.stdfix.uhkbits + libc.src.stdfix.kbits + libc.src.stdfix.ukbits + libc.src.stdfix.lkbits + libc.src.stdfix.ulkbits + ) +endif() + +set(TARGET_LLVMLIBC_ENTRYPOINTS + ${TARGET_LIBC_ENTRYPOINTS} + ${TARGET_LIBM_ENTRYPOINTS} +) diff --git a/libc/config/baremetal/aarch64/headers.txt b/libc/config/baremetal/aarch64/headers.txt new file mode 100644 index 0000000000000..6cc8a80455d3a --- /dev/null +++ b/libc/config/baremetal/aarch64/headers.txt @@ -0,0 +1,20 @@ +set(TARGET_PUBLIC_HEADERS + libc.include.assert + libc.include.ctype + libc.include.errno + libc.include.features + libc.include.fenv + libc.include.float + libc.include.inttypes + libc.include.math + libc.include.setjmp + libc.include.stdfix + libc.include.stdint + libc.include.stdio + libc.include.stdlib + libc.include.string + libc.include.strings + libc.include.sys_queue + libc.include.time + libc.include.uchar +) diff --git a/libc/config/baremetal/arm/entrypoints.txt b/libc/config/baremetal/arm/entrypoints.txt index 9027717acb4da..694cd7b1993ca 100644 --- a/libc/config/baremetal/arm/entrypoints.txt +++ b/libc/config/baremetal/arm/entrypoints.txt @@ -31,10 +31,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.setjmp.setjmp # string.h entrypoints - libc.src.string.bcmp - libc.src.string.bcopy - libc.src.string.bzero - libc.src.string.index libc.src.string.memccpy libc.src.string.memchr libc.src.string.memcmp @@ -45,10 +41,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.memrchr libc.src.string.memset libc.src.string.memset_explicit - libc.src.string.rindex libc.src.string.stpcpy libc.src.string.stpncpy - libc.src.string.strcasecmp libc.src.string.strcasestr libc.src.string.strcat libc.src.string.strchr @@ -62,7 +56,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strlcat libc.src.string.strlcpy libc.src.string.strlen - libc.src.string.strncasecmp libc.src.string.strncat libc.src.string.strncmp libc.src.string.strncpy @@ -76,6 +69,15 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strtok_r libc.src.string.strxfrm + # strings.h entrypoints + libc.src.strings.bcmp + libc.src.strings.bcopy + libc.src.strings.bzero + libc.src.strings.index + libc.src.strings.rindex + libc.src.strings.strcasecmp + libc.src.strings.strncasecmp + # inttypes.h entrypoints libc.src.inttypes.imaxabs libc.src.inttypes.imaxdiv @@ -182,7 +184,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdlib.div libc.src.stdlib.exit libc.src.stdlib.free - libc.src.stdlib.freelist_malloc libc.src.stdlib.labs libc.src.stdlib.ldiv libc.src.stdlib.llabs diff --git a/libc/config/baremetal/riscv/entrypoints.txt b/libc/config/baremetal/riscv/entrypoints.txt index afae2b3e082be..6dc5df830eb00 100644 --- a/libc/config/baremetal/riscv/entrypoints.txt +++ b/libc/config/baremetal/riscv/entrypoints.txt @@ -27,10 +27,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.errno.errno # string.h entrypoints - libc.src.string.bcmp - libc.src.string.bcopy - libc.src.string.bzero - libc.src.string.index libc.src.string.memccpy libc.src.string.memchr libc.src.string.memcmp @@ -41,10 +37,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.memrchr libc.src.string.memset libc.src.string.memset_explicit - libc.src.string.rindex libc.src.string.stpcpy libc.src.string.stpncpy - libc.src.string.strcasecmp libc.src.string.strcasestr libc.src.string.strcat libc.src.string.strchr @@ -58,7 +52,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strlcat libc.src.string.strlcpy libc.src.string.strlen - libc.src.string.strncasecmp libc.src.string.strncat libc.src.string.strncmp libc.src.string.strncpy @@ -72,6 +65,15 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strtok_r libc.src.string.strxfrm + # strings.h entrypoints + libc.src.strings.bcmp + libc.src.strings.bcopy + libc.src.strings.bzero + libc.src.strings.index + libc.src.strings.rindex + libc.src.strings.strcasecmp + libc.src.strings.strncasecmp + # inttypes.h entrypoints libc.src.inttypes.imaxabs libc.src.inttypes.imaxdiv @@ -178,7 +180,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.stdlib.div libc.src.stdlib.exit libc.src.stdlib.free - libc.src.stdlib.freelist_malloc libc.src.stdlib.labs libc.src.stdlib.ldiv libc.src.stdlib.llabs diff --git a/libc/config/darwin/arm/entrypoints.txt b/libc/config/darwin/arm/entrypoints.txt index 2d5dbeff48574..7972d285f963a 100644 --- a/libc/config/darwin/arm/entrypoints.txt +++ b/libc/config/darwin/arm/entrypoints.txt @@ -21,9 +21,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.errno.errno # string.h entrypoints - libc.src.string.bcmp - libc.src.string.bcopy - libc.src.string.bzero libc.src.string.memccpy libc.src.string.memchr libc.src.string.memcmp @@ -35,7 +32,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.memset libc.src.string.stpcpy libc.src.string.stpncpy - libc.src.string.strcasecmp libc.src.string.strcasestr libc.src.string.strcat libc.src.string.strchr @@ -46,7 +42,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strlcat libc.src.string.strlcpy libc.src.string.strlen - libc.src.string.strncasecmp libc.src.string.strncat libc.src.string.strncmp libc.src.string.strncpy @@ -62,6 +57,13 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strdup libc.src.string.strndup + # strings.h entrypoints + libc.src.strings.bcmp + libc.src.strings.bcopy + libc.src.strings.bzero + libc.src.strings.strcasecmp + libc.src.strings.strncasecmp + # inttypes.h entrypoints libc.src.inttypes.imaxabs libc.src.inttypes.imaxdiv diff --git a/libc/config/darwin/x86_64/entrypoints.txt b/libc/config/darwin/x86_64/entrypoints.txt index 64eeed18f3819..19230cde47198 100644 --- a/libc/config/darwin/x86_64/entrypoints.txt +++ b/libc/config/darwin/x86_64/entrypoints.txt @@ -18,11 +18,9 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.ctype.toupper # search.h entrypoints - libc.src.search.lfind + libc.src.search.lfind # string.h entrypoints - libc.src.string.bcmp - libc.src.string.bzero libc.src.string.memccpy libc.src.string.memchr libc.src.string.memcmp @@ -58,6 +56,10 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strdup libc.src.string.strndup + # strings.h entrypoints + libc.src.strings.bcmp + libc.src.strings.bzero + # inttypes.h entrypoints libc.src.inttypes.imaxabs libc.src.inttypes.imaxdiv diff --git a/libc/config/gpu/entrypoints.txt b/libc/config/gpu/entrypoints.txt index 38e9f2e685cae..e3ebd3ca47256 100644 --- a/libc/config/gpu/entrypoints.txt +++ b/libc/config/gpu/entrypoints.txt @@ -35,10 +35,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.ctype.toupper_l # string.h entrypoints - libc.src.string.bcmp - libc.src.string.bcopy - libc.src.string.bzero - libc.src.string.index libc.src.string.memccpy libc.src.string.memchr libc.src.string.memcmp @@ -48,10 +44,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.mempcpy libc.src.string.memrchr libc.src.string.memset - libc.src.string.rindex libc.src.string.stpcpy libc.src.string.stpncpy - libc.src.string.strcasecmp libc.src.string.strcasestr libc.src.string.strcat libc.src.string.strchr @@ -66,7 +60,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strlcat libc.src.string.strlcpy libc.src.string.strlen - libc.src.string.strncasecmp libc.src.string.strncat libc.src.string.strncmp libc.src.string.strncpy @@ -82,6 +75,15 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strxfrm libc.src.string.strxfrm_l + # strings.h entrypoints + libc.src.strings.bcmp + libc.src.strings.bcopy + libc.src.strings.bzero + libc.src.strings.index + libc.src.strings.rindex + libc.src.strings.strcasecmp + libc.src.strings.strncasecmp + # stdbit.h entrypoints libc.src.stdbit.stdc_bit_ceil_uc libc.src.stdbit.stdc_bit_ceil_ui diff --git a/libc/config/linux/aarch64/entrypoints.txt b/libc/config/linux/aarch64/entrypoints.txt index aa0b8ba0490e9..c2179938b40d1 100644 --- a/libc/config/linux/aarch64/entrypoints.txt +++ b/libc/config/linux/aarch64/entrypoints.txt @@ -45,10 +45,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sched.sched_yield # string.h entrypoints - libc.src.string.bcmp - libc.src.string.bcopy - libc.src.string.bzero - libc.src.string.index libc.src.string.memccpy libc.src.string.memchr libc.src.string.memcmp @@ -59,10 +55,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.memrchr libc.src.string.memset libc.src.string.memset_explicit - libc.src.string.rindex libc.src.string.stpcpy libc.src.string.stpncpy - libc.src.string.strcasecmp libc.src.string.strcasestr libc.src.string.strcat libc.src.string.strchr @@ -77,7 +71,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strlcat libc.src.string.strlcpy libc.src.string.strlen - libc.src.string.strncasecmp libc.src.string.strncat libc.src.string.strncmp libc.src.string.strncpy @@ -93,6 +86,15 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strtok_r libc.src.string.strxfrm + # strings.h entrypoints + libc.src.strings.bcmp + libc.src.strings.bcopy + libc.src.strings.bzero + libc.src.strings.index + libc.src.strings.rindex + libc.src.strings.strcasecmp + libc.src.strings.strncasecmp + # inttypes.h entrypoints libc.src.inttypes.imaxabs libc.src.inttypes.imaxdiv @@ -252,7 +254,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sys.mman.munlockall libc.src.sys.mman.munmap libc.src.sys.mman.remap_file_pages - libc.src.sys.mman.process_mrelease libc.src.sys.mman.posix_madvise libc.src.sys.mman.shm_open libc.src.sys.mman.shm_unlink @@ -366,6 +367,9 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.complex.cimag libc.src.complex.cimagf libc.src.complex.cimagl + libc.src.complex.conj + libc.src.complex.conjf + libc.src.complex.conjl # fenv.h entrypoints libc.src.fenv.feclearexcept @@ -617,6 +621,7 @@ if(LIBC_TYPES_HAS_FLOAT16) # complex.h C23 _Complex _Float16 entrypoints # libc.src.complex.crealf16 # libc.src.complex.cimagf16 + # libc.src.complex.conjf16 # math.h C23 _Float16 entrypoints libc.src.math.canonicalizef16 @@ -722,6 +727,7 @@ if(LIBC_TYPES_HAS_FLOAT128) # complex.h C23 _Complex _Float128 entrypoints libc.src.complex.crealf128 libc.src.complex.cimagf128 + libc.src.complex.conjf128 # math.h C23 _Float128 entrypoints libc.src.math.canonicalizef128 @@ -805,11 +811,11 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.dirent.opendir libc.src.dirent.readdir - # network.h entrypoints - libc.src.network.htonl - libc.src.network.htons - libc.src.network.ntohl - libc.src.network.ntohs + # arpa/inet.h entrypoints + libc.src.arpa.inet.htonl + libc.src.arpa.inet.htons + libc.src.arpa.inet.ntohl + libc.src.arpa.inet.ntohs # pthread.h entrypoints libc.src.pthread.pthread_atfork diff --git a/libc/config/linux/aarch64/headers.txt b/libc/config/linux/aarch64/headers.txt index f98af5744685f..05f15a0e4e5cb 100644 --- a/libc/config/linux/aarch64/headers.txt +++ b/libc/config/linux/aarch64/headers.txt @@ -1,5 +1,6 @@ set(TARGET_PUBLIC_HEADERS libc.include.assert + libc.include.complex libc.include.ctype libc.include.dlfcn libc.include.elf diff --git a/libc/config/linux/arm/entrypoints.txt b/libc/config/linux/arm/entrypoints.txt index 31d81de06fb6b..f5e9827727396 100644 --- a/libc/config/linux/arm/entrypoints.txt +++ b/libc/config/linux/arm/entrypoints.txt @@ -21,10 +21,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.errno.errno # string.h entrypoints - libc.src.string.bcmp - libc.src.string.bcopy - libc.src.string.bzero - libc.src.string.index libc.src.string.memccpy libc.src.string.memchr libc.src.string.memcmp @@ -34,10 +30,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.mempcpy libc.src.string.memrchr libc.src.string.memset - libc.src.string.rindex libc.src.string.stpcpy libc.src.string.stpncpy - libc.src.string.strcasecmp libc.src.string.strcasestr libc.src.string.strcat libc.src.string.strchr @@ -48,7 +42,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strlcat libc.src.string.strlcpy libc.src.string.strlen - libc.src.string.strncasecmp libc.src.string.strncat libc.src.string.strncmp libc.src.string.strncpy @@ -61,6 +54,15 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strtok libc.src.string.strtok_r + # strings.h entrypoints + libc.src.strings.bcmp + libc.src.strings.bcopy + libc.src.strings.bzero + libc.src.strings.index + libc.src.strings.rindex + libc.src.strings.strcasecmp + libc.src.strings.strncasecmp + # inttypes.h entrypoints libc.src.inttypes.imaxabs libc.src.inttypes.imaxdiv @@ -207,6 +209,9 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.complex.cimag libc.src.complex.cimagf libc.src.complex.cimagl + libc.src.complex.conj + libc.src.complex.conjf + libc.src.complex.conjl # fenv.h entrypoints libc.src.fenv.feclearexcept diff --git a/libc/config/linux/arm/headers.txt b/libc/config/linux/arm/headers.txt index 6576db1f85269..9aabac5dea33c 100644 --- a/libc/config/linux/arm/headers.txt +++ b/libc/config/linux/arm/headers.txt @@ -1,4 +1,5 @@ set(TARGET_PUBLIC_HEADERS + libc.include.complex libc.include.ctype libc.include.errno libc.include.fenv diff --git a/libc/config/linux/riscv/entrypoints.txt b/libc/config/linux/riscv/entrypoints.txt index fedc5002d8c24..e2df6aca38bf9 100644 --- a/libc/config/linux/riscv/entrypoints.txt +++ b/libc/config/linux/riscv/entrypoints.txt @@ -45,10 +45,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sched.sched_yield # string.h entrypoints - libc.src.string.bcmp - libc.src.string.bcopy - libc.src.string.bzero - libc.src.string.index libc.src.string.memccpy libc.src.string.memchr libc.src.string.memcmp @@ -59,10 +55,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.memrchr libc.src.string.memset libc.src.string.memset_explicit - libc.src.string.rindex libc.src.string.stpcpy libc.src.string.stpncpy - libc.src.string.strcasecmp libc.src.string.strcasestr libc.src.string.strcat libc.src.string.strchr @@ -77,7 +71,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strlcat libc.src.string.strlcpy libc.src.string.strlen - libc.src.string.strncasecmp libc.src.string.strncat libc.src.string.strncmp libc.src.string.strncpy @@ -93,6 +86,14 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strtok_r libc.src.string.strxfrm + # strings.h entrypoints + libc.src.strings.index + libc.src.strings.rindex + libc.src.strings.bcmp + libc.src.strings.bcopy + libc.src.strings.bzero + libc.src.strings.strcasecmp + # inttypes.h entrypoints libc.src.inttypes.imaxabs libc.src.inttypes.imaxdiv @@ -251,8 +252,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sys.mman.munmap libc.src.sys.mman.remap_file_pages libc.src.sys.mman.posix_madvise - # TODO: disabled due to buildbot failure. further investigation needed. - # libc.src.sys.mman.process_mrelease libc.src.sys.mman.shm_open libc.src.sys.mman.shm_unlink @@ -365,6 +364,9 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.complex.cimag libc.src.complex.cimagf libc.src.complex.cimagl + libc.src.complex.conj + libc.src.complex.conjf + libc.src.complex.conjl # fenv.h entrypoints libc.src.fenv.feclearexcept @@ -620,6 +622,7 @@ if(LIBC_TYPES_HAS_FLOAT128) # complex.h C23 _Complex _Float128 entrypoints libc.src.complex.crealf128 libc.src.complex.cimagf128 + libc.src.complex.conjf128 # math.h C23 _Float128 entrypoints libc.src.math.canonicalizef128 @@ -749,11 +752,11 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.dirent.opendir libc.src.dirent.readdir - # network.h entrypoints - libc.src.network.htonl - libc.src.network.htons - libc.src.network.ntohl - libc.src.network.ntohs + # arpa/inet.h entrypoints + libc.src.arpa.inet.htonl + libc.src.arpa.inet.htons + libc.src.arpa.inet.ntohl + libc.src.arpa.inet.ntohs # pthread.h entrypoints libc.src.pthread.pthread_atfork diff --git a/libc/config/linux/riscv/headers.txt b/libc/config/linux/riscv/headers.txt index 41c343f71998b..b38659e0b8daf 100644 --- a/libc/config/linux/riscv/headers.txt +++ b/libc/config/linux/riscv/headers.txt @@ -1,5 +1,6 @@ set(TARGET_PUBLIC_HEADERS libc.include.assert + libc.include.complex libc.include.ctype libc.include.dirent libc.include.dlfcn diff --git a/libc/config/linux/x86_64/entrypoints.txt b/libc/config/linux/x86_64/entrypoints.txt index 5e9cc71279ab1..e236ad62261d8 100644 --- a/libc/config/linux/x86_64/entrypoints.txt +++ b/libc/config/linux/x86_64/entrypoints.txt @@ -45,10 +45,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sched.sched_yield # string.h entrypoints - libc.src.string.bcmp - libc.src.string.bcopy - libc.src.string.bzero - libc.src.string.index libc.src.string.memccpy libc.src.string.memchr libc.src.string.memcmp @@ -59,10 +55,8 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.memrchr libc.src.string.memset libc.src.string.memset_explicit - libc.src.string.rindex libc.src.string.stpcpy libc.src.string.stpncpy - libc.src.string.strcasecmp libc.src.string.strcasestr libc.src.string.strcat libc.src.string.strchr @@ -77,7 +71,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strlcat libc.src.string.strlcpy libc.src.string.strlen - libc.src.string.strncasecmp libc.src.string.strncat libc.src.string.strncmp libc.src.string.strncpy @@ -93,6 +86,15 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strtok_r libc.src.string.strxfrm + # strings.h entrypoints + libc.src.strings.bcmp + libc.src.strings.bcopy + libc.src.strings.bzero + libc.src.strings.index + libc.src.strings.rindex + libc.src.strings.strcasecmp + libc.src.strings.strncasecmp + # inttypes.h entrypoints libc.src.inttypes.imaxabs libc.src.inttypes.imaxdiv @@ -252,7 +254,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.sys.mman.munmap libc.src.sys.mman.remap_file_pages libc.src.sys.mman.posix_madvise - libc.src.sys.mman.process_mrelease libc.src.sys.mman.shm_open libc.src.sys.mman.shm_unlink @@ -366,6 +367,9 @@ set(TARGET_LIBM_ENTRYPOINTS libc.src.complex.cimag libc.src.complex.cimagf libc.src.complex.cimagl + libc.src.complex.conj + libc.src.complex.conjf + libc.src.complex.conjl # fenv.h entrypoints libc.src.fenv.feclearexcept @@ -622,11 +626,13 @@ if(LIBC_TYPES_HAS_FLOAT16) # complex.h C23 _Complex _Float16 entrypoints libc.src.complex.crealf16 libc.src.complex.cimagf16 + libc.src.complex.conjf16 # math.h C23 _Float16 entrypoints libc.src.math.canonicalizef16 libc.src.math.ceilf16 libc.src.math.copysignf16 + libc.src.math.cosf16 libc.src.math.coshf16 libc.src.math.cospif16 libc.src.math.exp10f16 @@ -731,6 +737,7 @@ if(LIBC_TYPES_HAS_FLOAT128) # complex.h C23 _Complex _Float128 entrypoints # libc.src.complex.crealf128 # libc.src.complex.cimagf128 + # libc.src.complex.conjf128 # math.h C23 _Float128 entrypoints libc.src.math.canonicalizef128 @@ -889,11 +896,11 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.dirent.opendir libc.src.dirent.readdir - # network.h entrypoints - libc.src.network.htonl - libc.src.network.htons - libc.src.network.ntohl - libc.src.network.ntohs + # arpa/inet.h entrypoints + libc.src.arpa.inet.htonl + libc.src.arpa.inet.htons + libc.src.arpa.inet.ntohl + libc.src.arpa.inet.ntohs # pthread.h entrypoints libc.src.pthread.pthread_atfork diff --git a/libc/config/linux/x86_64/headers.txt b/libc/config/linux/x86_64/headers.txt index e0c04b381492d..8750100302ea7 100644 --- a/libc/config/linux/x86_64/headers.txt +++ b/libc/config/linux/x86_64/headers.txt @@ -1,5 +1,6 @@ set(TARGET_PUBLIC_HEADERS libc.include.assert + libc.include.complex libc.include.ctype libc.include.dirent libc.include.dlfcn diff --git a/libc/config/windows/entrypoints.txt b/libc/config/windows/entrypoints.txt index 8f0b50bcc83ea..4ecc3ada9c768 100644 --- a/libc/config/windows/entrypoints.txt +++ b/libc/config/windows/entrypoints.txt @@ -18,9 +18,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.ctype.toupper # string.h entrypoints - libc.src.string.bcmp - libc.src.string.bcopy - libc.src.string.bzero libc.src.string.memccpy libc.src.string.memchr libc.src.string.memcmp @@ -32,7 +29,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.memset libc.src.string.stpcpy libc.src.string.stpncpy - libc.src.string.strcasecmp libc.src.string.strcasestr libc.src.string.strcat libc.src.string.strchr @@ -43,7 +39,6 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strlcat libc.src.string.strlcpy libc.src.string.strlen - libc.src.string.strncasecmp libc.src.string.strncat libc.src.string.strncmp libc.src.string.strncpy @@ -59,6 +54,13 @@ set(TARGET_LIBC_ENTRYPOINTS libc.src.string.strdup libc.src.string.strndup + # strings.h entrypoints + libc.src.strings.bcmp + libc.src.strings.bcopy + libc.src.strings.bzero + libc.src.strings.strcasecmp + libc.src.strings.strncasecmp + # inttypes.h entrypoints libc.src.inttypes.imaxabs libc.src.inttypes.imaxdiv @@ -95,6 +97,10 @@ set(TARGET_LIBC_ENTRYPOINTS # errno.h entrypoints libc.src.errno.errno + + # time.h entrypoints + libc.src.time.time + libc.src.time.clock_getres ) set(TARGET_LIBM_ENTRYPOINTS diff --git a/libc/docs/arch_support.rst b/libc/docs/arch_support.rst new file mode 100644 index 0000000000000..6ab0486c7ea22 --- /dev/null +++ b/libc/docs/arch_support.rst @@ -0,0 +1,19 @@ +Architecture Support +==================== + +The currently continuously tested architectures are: + +* aarch64 +* amdgpu +* arm +* nvptx +* riscv32 +* riscv64 +* x86_64 + +i386 support is [in the works](https://github.com/llvm/llvm-project/issues/93709). + +See "`Bringup on a New OS or Architecture `__" for more +information. Please do first file a bug in +`our issue tracker `__ before +starting a port that you plan to upstream. diff --git a/libc/docs/ctype.rst b/libc/docs/ctype.rst deleted file mode 100644 index 828785c9b6708..0000000000000 --- a/libc/docs/ctype.rst +++ /dev/null @@ -1,74 +0,0 @@ -.. include:: check.rst - -======= -ctype.h -======= - -Functions -========= - -.. list-table:: - :widths: auto - :align: center - :header-rows: 1 - - * - Function - - Implemented - - C23 Standard Section - - POSIX.1-2017 Standard Section - * - isalnum - - |check| - - 7.4.1.1 - - - * - isalpha - - |check| - - 7.4.1.2 - - - * - isblank - - |check| - - 7.4.1.3 - - - * - iscntrl - - |check| - - 7.4.1.4 - - - * - isdigit - - |check| - - 7.4.1.5 - - - * - isgraph - - |check| - - 7.4.1.6 - - - * - islower - - |check| - - 7.4.1.7 - - - * - isprint - - |check| - - 7.4.1.8 - - - * - ispunct - - |check| - - 7.4.1.9 - - - * - isspace - - |check| - - 7.4.1.10 - - - * - isupper - - |check| - - 7.4.1.11 - - - * - isxdigit - - |check| - - 7.4.1.12 - - - * - tolower - - |check| - - 7.4.2.1 - - - * - toupper - - |check| - - 7.4.2.2 - - diff --git a/libc/docs/dev/source_tree_layout.rst b/libc/docs/dev/source_tree_layout.rst index 0010f138317b5..bd9d6ca453e08 100644 --- a/libc/docs/dev/source_tree_layout.rst +++ b/libc/docs/dev/source_tree_layout.rst @@ -29,8 +29,7 @@ The ``benchmarks`` directory ---------------------------- The ``benchmarks`` directory contains LLVM-libc's benchmarking utilities. These -are mostly used for the memory functions. This also includes the automemcpy -subdirectory for automatic generation of optimized memory functions. +are mostly used for the memory functions. The ``config`` directory ------------------------ diff --git a/libc/docs/fenv.rst b/libc/docs/fenv.rst deleted file mode 100644 index 2492e22d2fd78..0000000000000 --- a/libc/docs/fenv.rst +++ /dev/null @@ -1,175 +0,0 @@ -.. include:: check.rst - -====== -fenv.h -====== - -Macros -====== - -.. list-table:: - :widths: auto - :align: center - :header-rows: 1 - - * - Macro - - Implemented - - C23 Standard Section - - POSIX.1-2017 Standard Section - * - FE_ALL_EXCEPT - - |check| - - 7.6.12 - - - * - FE_DEC_DOWNWARD - - - - 7.6.14 - - - * - FE_DEC_TONEAREST - - - - 7.6.14 - - - * - FE_DEC_TONEARESTFROMZERO - - - - 7.6.14 - - - * - FE_DEC_TOWARDZERO - - - - 7.6.14 - - - * - FE_DEC_UPWARD - - - - 7.6.14 - - - * - FE_DFL_ENV - - |check| - - 7.6.17 - - - * - FE_DFL_MODE - - - - 7.6.11 - - - * - FE_DIVBYZERO - - |check| - - 7.6.9 - - - * - FE_DOWNARD - - - - 7.6.13 - - - * - FE_INEXACT - - |check| - - 7.6.9 - - - * - FE_INVALID - - |check| - - 7.6.9 - - - * - FE_OVERFLOW - - |check| - - 7.6.9 - - - * - FE_TONEAREST - - |check| - - 7.6.13 - - - * - FE_TONEARESTFROMZERO - - - - 7.6.13 - - - * - FE_TOWARDZERO - - |check| - - 7.6.13 - - - * - FE_UNDERFLOW - - |check| - - 7.6.9 - - - * - FE_UPWARD - - |check| - - 7.6.13 - - - * - __STDC_VERSION_FENV_H__ - - - - 7.6.5 - - - -Functions -========= - -.. list-table:: - :widths: auto - :align: center - :header-rows: 1 - - * - Function - - Implemented - - C23 Standard Section - - POSIX.1-2017 Standard Section - * - fe_dec_getround - - - - 7.6.5.3 - - - * - fe_dec_setround - - - - 7.6.5.6 - - - * - feclearexcept - - |check| - - 7.6.4.1 - - - * - fegetenv - - |check| - - 7.6.6.1 - - - * - fegetexceptflag - - |check| - - 7.6.4.2 - - - * - fegetmode - - - - 7.6.5.1 - - - * - fegetround - - |check| - - 7.6.5.2 - - - * - feholdexcept - - |check| - - 7.6.6.2 - - - * - feraiseexcept - - |check| - - 7.6.4.3 - - - * - fesetenv - - |check| - - 7.6.6.3 - - - * - fesetexcept - - |check| - - 7.6.4.4 - - - * - fesetexceptflag - - |check| - - 7.6.4.5 - - - * - fesetmode - - - - 7.6.5.4 - - - * - fesetround - - |check| - - 7.6.5.5 - - - * - fetestexcept - - |check| - - 7.6.4.7 - - - * - fetestexceptflag - - |check| - - 7.6.4.6 - - - * - feupdateenv - - |check| - - 7.6.6.4 - - diff --git a/libc/docs/gpu/rpc.rst b/libc/docs/gpu/rpc.rst index e1244154341e9..0d169c7db9a50 100644 --- a/libc/docs/gpu/rpc.rst +++ b/libc/docs/gpu/rpc.rst @@ -92,20 +92,6 @@ asynchronous operations that do not need to wait until the server has completed them. If an operation requires more data than the fixed size buffer, we simply send multiple packets back and forth in a streaming fashion. -Server Library --------------- - -The RPC server's basic functionality is provided by the LLVM C library. A static -library called ``libllvmlibc_rpc_server.a`` includes handling for the basic -operations, such as printing or exiting. This has a small API that handles -setting up the unified buffer and an interface to check the opcodes. - -Some operations are too divergent to provide generic implementations for, such -as allocating device accessible memory. For these cases, we provide a callback -registration scheme to add a custom handler for any given opcode through the -port API. More information can be found in the installed header -``/include/llvmlibc_rpc_server.h``. - Client Example -------------- @@ -183,7 +169,7 @@ CUDA Server Example The following code shows an example of using the exported RPC interface along with the C library to manually configure a working server using the CUDA -language. Other runtimes can use the presence of the ``__llvm_libc_rpc_client`` +language. Other runtimes can use the presence of the ``__llvm_rpc_client`` in the GPU executable as an indicator for whether or not the server can be checked. These details should ideally be handled by the GPU language runtime, but the following example shows how it can be used by a standard user. @@ -196,53 +182,16 @@ but the following example shows how it can be used by a standard user. #include #include - #include + #include + #include [[noreturn]] void handle_error(cudaError_t err) { fprintf(stderr, "CUDA error: %s\n", cudaGetErrorString(err)); exit(EXIT_FAILURE); } - [[noreturn]] void handle_error(rpc_status_t err) { - fprintf(stderr, "RPC error: %d\n", err); - exit(EXIT_FAILURE); - } - - // The handle to the RPC client provided by the C library. - extern "C" __device__ void *__llvm_libc_rpc_client; - - __global__ void get_client_ptr(void **ptr) { *ptr = __llvm_libc_rpc_client; } - - // Obtain the RPC client's handle from the device. The CUDA language cannot look - // up the symbol directly like the driver API, so we launch a kernel to read it. - void *get_rpc_client() { - void *rpc_client = nullptr; - void **rpc_client_d = nullptr; - - if (cudaError_t err = cudaMalloc(&rpc_client_d, sizeof(void *))) - handle_error(err); - get_client_ptr<<<1, 1>>>(rpc_client_d); - if (cudaError_t err = cudaDeviceSynchronize()) - handle_error(err); - if (cudaError_t err = cudaMemcpy(&rpc_client, rpc_client_d, sizeof(void *), - cudaMemcpyDeviceToHost)) - handle_error(err); - return rpc_client; - } - - // Routines to allocate mapped memory that both the host and the device can - // access asychonrously to communicate with each other. - void *alloc_host(size_t size, void *) { - void *sharable_ptr; - if (cudaError_t err = cudaMallocHost(&sharable_ptr, sizeof(void *))) - handle_error(err); - return sharable_ptr; - }; - - void free_host(void *ptr, void *) { - if (cudaError_t err = cudaFreeHost(ptr)) - handle_error(err); - } + // Routes the library symbol into the CUDA runtime interface. + [[gnu::weak]] __device__ rpc::Client client asm("__llvm_rpc_client"); // The device-side overload of the standard C function to call. extern "C" __device__ int puts(const char *); @@ -251,18 +200,23 @@ but the following example shows how it can be used by a standard user. __global__ void hello() { puts("Hello world!"); } int main() { - // Initialize the RPC server to run on the given device. - rpc_device_t device; - if (rpc_status_t err = - rpc_server_init(&device, RPC_MAXIMUM_PORT_COUNT, - /*warp_size=*/32, alloc_host, /*data=*/nullptr)) + void *rpc_client = nullptr; + if (cudaError_t err = cudaGetSymbolAddress(&rpc_client, client)) + handle_error(err); + + // Initialize the RPC client and server interface. + uint32_t warp_size = 32; + void *rpc_buffer = nullptr; + if (cudaError_t err = cudaMallocHost( + &rpc_buffer, + rpc::Server::allocation_size(warp_size, rpc::MAX_PORT_COUNT))) handle_error(err); + rpc::Server server(rpc::MAX_PORT_COUNT, rpc_buffer); + rpc::Client client(rpc::MAX_PORT_COUNT, rpc_buffer); - // Initialize the RPC client by copying the buffer to the device's handle. - void *rpc_client = get_rpc_client(); - if (cudaError_t err = - cudaMemcpy(rpc_client, rpc_get_client_buffer(device), - rpc_get_client_size(), cudaMemcpyHostToDevice)) + // Initialize the client on the device so it can communicate with the server. + if (cudaError_t err = cudaMemcpy(rpc_client, &client, sizeof(rpc::Client), + cudaMemcpyHostToDevice)) handle_error(err); cudaStream_t stream; @@ -274,28 +228,25 @@ but the following example shows how it can be used by a standard user. // While the kernel is executing, check the RPC server for work to do. // Requires non-blocking CUDA kernels but avoids a separate thread. - while (cudaStreamQuery(stream) == cudaErrorNotReady) - if (rpc_status_t err = rpc_handle_server(device)) - handle_error(err); - - // Shut down the server running on the given device. - if (rpc_status_t err = - rpc_server_shutdown(device, free_host, /*data=*/nullptr)) - handle_error(err); - - return EXIT_SUCCESS; + do { + auto port = server.try_open(warp_size, /*index=*/0); + // From libllvmlibc_rpc_server.a in the installation. + if (port) + handle_libc_opcodes(*port, warp_size); + } while (cudaStreamQuery(stream) == cudaErrorNotReady); } The above code must be compiled in CUDA's relocatable device code mode and with the advanced offloading driver to link in the library. Currently this can be done with the following invocation. Using LTO avoids the overhead normally -associated with relocatable device code linking. +associated with relocatable device code linking. The C library for GPUs is +linked in by forwarding the static library to the device-side link job. .. code-block:: sh - $> clang++ -x cuda rpc.cpp --offload-arch=native -fgpu-rdc -lcudart -lcgpu-nvptx \ + $> clang++ -x cuda rpc.cpp --offload-arch=native -fgpu-rdc -lcudart \ -Iinclude -L/lib -lllvmlibc_rpc_server \ - -O3 -foffload-lto -o hello + -Xoffload-linker -lc -O3 -foffload-lto -o hello $> ./hello Hello world! @@ -304,4 +255,5 @@ Extensions The opcode is a 32-bit integer that must be unique to the requested operation. All opcodes used by ``libc`` internally have the character ``c`` in the most -significant byte. +significant byte. Any other opcode is available for use outside of the ``libc`` +implementation. diff --git a/libc/docs/gpu/using.rst b/libc/docs/gpu/using.rst index e56b6f634bb31..1c1f9c9bfb0c6 100644 --- a/libc/docs/gpu/using.rst +++ b/libc/docs/gpu/using.rst @@ -99,39 +99,6 @@ threads and two blocks. Including the wrapper headers, linking the C library, and running the :ref:`RPC server` are all handled automatically by the compiler and runtime. -Binary format -^^^^^^^^^^^^^ - -The ``libcgpu.a`` static archive is a fat-binary containing LLVM-IR for each -supported target device. The supported architectures can be seen using LLVM's -``llvm-objdump`` with the ``--offloading`` flag: - -.. code-block:: sh - - $> llvm-objdump --offloading libcgpu-amdgpu.a - libcgpu-amdgpu.a(strcmp.cpp.o): file format elf64-x86-64 - - OFFLOADING IMAGE [0]: - kind llvm ir - arch generic - triple amdgcn-amd-amdhsa - producer none - ... - -Because the device code is stored inside a fat binary, it can be difficult to -inspect the resulting code. This can be done using the following utilities: - -.. code-block:: sh - - $> llvm-ar x libcgpu.a strcmp.cpp.o - $> clang-offload-packager strcmp.cpp.o --image=arch=generic,file=strcmp.bc - $> opt -S out.bc - ... - -Please note that this fat binary format is provided for compatibility with -existing offloading toolchains. The implementation in ``libc`` does not depend -on any existing offloading languages and is completely freestanding. - Direct compilation ------------------ @@ -246,7 +213,7 @@ compilation. Using link time optimization will help hide this. .. code-block:: sh - $> clang hello.c --target=nvptx64-nvidia-cuda -mcpu=native -flto -lc /lib/nvptx64-nvidia-cuda/crt1.o + $> clang hello.c --target=nvptx64-nvidia-cuda -march=native -flto -lc /lib/nvptx64-nvidia-cuda/crt1.o $> nvptx-loader --threads 2 --blocks 2 a.out Hello from NVPTX! Hello from NVPTX! diff --git a/libc/docs/header_gen_scheme.svg b/libc/docs/header_gen_scheme.svg deleted file mode 100644 index 2b2318b1a045a..0000000000000 --- a/libc/docs/header_gen_scheme.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/libc/docs/headers/arpa/inet.rst b/libc/docs/headers/arpa/inet.rst new file mode 100644 index 0000000000000..c82ca5427fbbb --- /dev/null +++ b/libc/docs/headers/arpa/inet.rst @@ -0,0 +1,50 @@ +.. include:: ../../check.rst + +=========== +arpa/inet.h +=========== + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX.1-2024 Standard Section + * - htonl + - |check| + - + - + * - htons + - |check| + - + - + * - inet_addr + - + - + - + * - inet_ntoa + - + - + - + * - inet_ntop + - + - + - + * - inet_pton + - + - + - + * - ntohl + - |check| + - + - + * - ntohs + - |check| + - + - diff --git a/libc/docs/headers/assert.rst b/libc/docs/headers/assert.rst new file mode 100644 index 0000000000000..682170755ba43 --- /dev/null +++ b/libc/docs/headers/assert.rst @@ -0,0 +1,27 @@ +.. include:: ../check.rst + +======== +assert.h +======== + +Macros +====== + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Macro + - Implemented + - C23 Standard Section + - POSIX Docs + * - __STDC_VERSION_ASSERT_H__ + - |check| + - 7.2.1 + - + * - assert + - + - 7.2.1 + - `POSIX.1-2024 `__ + diff --git a/libc/docs/complex.rst b/libc/docs/headers/complex.rst similarity index 98% rename from libc/docs/complex.rst rename to libc/docs/headers/complex.rst index 1e74f16b60e66..b6a340543fad1 100644 --- a/libc/docs/complex.rst +++ b/libc/docs/headers/complex.rst @@ -1,4 +1,4 @@ -.. include:: check.rst +.. include:: ../check.rst ========= complex.h @@ -57,7 +57,7 @@ Functions +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | cimag | |check| | |check| | |check| | |check| | |check| | 7.3.9.2 | N/A | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| conj | | | | | | 7.3.9.4 | N/A | +| conj | |check| | |check| | |check| | |check| | |check| | 7.3.9.4 | N/A | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | cproj | | | | | | 7.3.9.5 | N/A | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ diff --git a/libc/docs/headers/ctype.rst b/libc/docs/headers/ctype.rst new file mode 100644 index 0000000000000..9b5b1574fd274 --- /dev/null +++ b/libc/docs/headers/ctype.rst @@ -0,0 +1,130 @@ +.. include:: ../check.rst + +======= +ctype.h +======= + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX Docs + * - isalnum + - |check| + - 7.4.1.1 + - `POSIX.1-2024 `__ + * - isalnum_l + - |check| + - + - `POSIX.1-2024 `__ + * - isalpha + - |check| + - 7.4.1.2 + - `POSIX.1-2024 `__ + * - isalpha_l + - |check| + - + - `POSIX.1-2024 `__ + * - isblank + - |check| + - 7.4.1.3 + - `POSIX.1-2024 `__ + * - isblank_l + - |check| + - + - `POSIX.1-2024 `__ + * - iscntrl + - |check| + - 7.4.1.4 + - `POSIX.1-2024 `__ + * - iscntrl_l + - |check| + - + - `POSIX.1-2024 `__ + * - isdigit + - |check| + - 7.4.1.5 + - `POSIX.1-2024 `__ + * - isdigit_l + - |check| + - + - `POSIX.1-2024 `__ + * - isgraph + - |check| + - 7.4.1.6 + - `POSIX.1-2024 `__ + * - isgraph_l + - |check| + - + - `POSIX.1-2024 `__ + * - islower + - |check| + - 7.4.1.7 + - `POSIX.1-2024 `__ + * - islower_l + - |check| + - + - `POSIX.1-2024 `__ + * - isprint + - |check| + - 7.4.1.8 + - `POSIX.1-2024 `__ + * - isprint_l + - |check| + - + - `POSIX.1-2024 `__ + * - ispunct + - |check| + - 7.4.1.9 + - `POSIX.1-2024 `__ + * - ispunct_l + - |check| + - + - `POSIX.1-2024 `__ + * - isspace + - |check| + - 7.4.1.10 + - `POSIX.1-2024 `__ + * - isspace_l + - |check| + - + - `POSIX.1-2024 `__ + * - isupper + - |check| + - 7.4.1.11 + - `POSIX.1-2024 `__ + * - isupper_l + - |check| + - + - `POSIX.1-2024 `__ + * - isxdigit + - |check| + - 7.4.1.12 + - `POSIX.1-2024 `__ + * - isxdigit_l + - |check| + - + - `POSIX.1-2024 `__ + * - tolower + - |check| + - 7.4.2.1 + - `POSIX.1-2024 `__ + * - tolower_l + - |check| + - + - `POSIX.1-2024 `__ + * - toupper + - |check| + - 7.4.2.2 + - `POSIX.1-2024 `__ + * - toupper_l + - |check| + - + - `POSIX.1-2024 `__ diff --git a/libc/docs/headers/errno.rst b/libc/docs/headers/errno.rst new file mode 100644 index 0000000000000..b2b2e62728e1a --- /dev/null +++ b/libc/docs/headers/errno.rst @@ -0,0 +1,35 @@ +.. include:: ../check.rst + +======= +errno.h +======= + +Macros +====== + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Macro + - Implemented + - C23 Standard Section + - POSIX Docs + * - EDOM + - + - 7.5 + - `POSIX.1-2024 `__ + * - EILSEQ + - + - 7.5 + - `POSIX.1-2024 `__ + * - ERANGE + - + - 7.5 + - `POSIX.1-2024 `__ + * - errno + - + - 7.5 + - `POSIX.1-2024 `__ + diff --git a/libc/docs/headers/fenv.rst b/libc/docs/headers/fenv.rst new file mode 100644 index 0000000000000..d0e3c5dda6d00 --- /dev/null +++ b/libc/docs/headers/fenv.rst @@ -0,0 +1,175 @@ +.. include:: ../check.rst + +====== +fenv.h +====== + +Macros +====== + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Macro + - Implemented + - C23 Standard Section + - POSIX Docs + * - FE_ALL_EXCEPT + - |check| + - 7.6.12 + - `POSIX.1-2024 `__ + * - FE_DEC_DOWNWARD + - + - 7.6.14 + - + * - FE_DEC_TONEAREST + - + - 7.6.14 + - + * - FE_DEC_TONEARESTFROMZERO + - + - 7.6.14 + - + * - FE_DEC_TOWARDZERO + - + - 7.6.14 + - + * - FE_DEC_UPWARD + - + - 7.6.14 + - + * - FE_DFL_ENV + - |check| + - 7.6.17 + - `POSIX.1-2024 `__ + * - FE_DFL_MODE + - + - 7.6.11 + - + * - FE_DIVBYZERO + - |check| + - 7.6.9 + - `POSIX.1-2024 `__ + * - FE_DOWNWARD + - |check| + - 7.6.13 + - `POSIX.1-2024 `__ + * - FE_INEXACT + - |check| + - 7.6.9 + - `POSIX.1-2024 `__ + * - FE_INVALID + - |check| + - 7.6.9 + - `POSIX.1-2024 `__ + * - FE_OVERFLOW + - |check| + - 7.6.9 + - `POSIX.1-2024 `__ + * - FE_TONEAREST + - |check| + - 7.6.13 + - `POSIX.1-2024 `__ + * - FE_TONEARESTFROMZERO + - + - 7.6.13 + - + * - FE_TOWARDZERO + - |check| + - 7.6.13 + - `POSIX.1-2024 `__ + * - FE_UNDERFLOW + - |check| + - 7.6.9 + - `POSIX.1-2024 `__ + * - FE_UPWARD + - |check| + - 7.6.13 + - `POSIX.1-2024 `__ + * - __STDC_VERSION_FENV_H__ + - + - 7.6.5 + - + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX Docs + * - fe_dec_getround + - + - 7.6.5.3 + - + * - fe_dec_setround + - + - 7.6.5.6 + - + * - feclearexcept + - |check| + - 7.6.4.1 + - `POSIX.1-2024 `__ + * - fegetenv + - |check| + - 7.6.6.1 + - `POSIX.1-2024 `__ + * - fegetexceptflag + - |check| + - 7.6.4.2 + - `POSIX.1-2024 `__ + * - fegetmode + - + - 7.6.5.1 + - + * - fegetround + - |check| + - 7.6.5.2 + - `POSIX.1-2024 `__ + * - feholdexcept + - |check| + - 7.6.6.2 + - `POSIX.1-2024 `__ + * - feraiseexcept + - |check| + - 7.6.4.3 + - `POSIX.1-2024 `__ + * - fesetenv + - |check| + - 7.6.6.3 + - `POSIX.1-2024 `__ + * - fesetexcept + - |check| + - 7.6.4.4 + - + * - fesetexceptflag + - |check| + - 7.6.4.5 + - `POSIX.1-2024 `__ + * - fesetmode + - + - 7.6.5.4 + - + * - fesetround + - |check| + - 7.6.5.5 + - `POSIX.1-2024 `__ + * - fetestexcept + - |check| + - 7.6.4.7 + - `POSIX.1-2024 `__ + * - fetestexceptflag + - |check| + - 7.6.4.6 + - + * - feupdateenv + - |check| + - 7.6.6.4 + - `POSIX.1-2024 `__ diff --git a/libc/docs/headers/float.rst b/libc/docs/headers/float.rst new file mode 100644 index 0000000000000..8ef0f3a05020c --- /dev/null +++ b/libc/docs/headers/float.rst @@ -0,0 +1,227 @@ +.. include:: ../check.rst + +======= +float.h +======= + +Macros +====== + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Macro + - Implemented + - C23 Standard Section + - POSIX Docs + * - DBL_DECIMAL_DIG + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - DBL_DIG + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - DBL_EPSILON + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - DBL_HAS_SUBNORM + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - DBL_IS_IEC_60559 + - + - 5.3.5.3.3 + - + * - DBL_MANT_DIG + - |check| + - 5.3.5.3.3 + - + * - DBL_MAX + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - DBL_MAX_10_EXP + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - DBL_MAX_EXP + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - DBL_MIN + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - DBL_MIN_10_EXP + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - DBL_MIN_EXP + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - DBL_NORM_MAX + - + - 5.3.5.3.3 + - + * - DBL_SNAN + - + - 5.3.5.3.3 + - + * - DBL_TRUE_MIN + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - DECIMAL_DIG + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_DECIMAL_DIG + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_DIG + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_EPSILON + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_EVAL_METHOD + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_HAS_SUBNORM + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_IS_IEC_60559 + - + - 5.3.5.3.3 + - + * - FLT_MANT_DIG + - |check| + - 5.3.5.3.3 + - + * - FLT_MAX + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_MAX_10_EXP + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_MAX_EXP + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_MIN + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_MIN_10_EXP + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_MIN_EXP + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_NORM_MAX + - + - 5.3.5.3.3 + - + * - FLT_RADIX + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_ROUNDS + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - FLT_SNAN + - + - 5.3.5.3.3 + - + * - FLT_TRUE_MIN + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - INFINITY + - + - 5.3.5.3.3 + - + * - LDBL_DECIMAL_DIG + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - LDBL_DIG + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - LDBL_EPSILON + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - LDBL_HAS_SUBNORM + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - LDBL_IS_IEC_60559 + - + - 5.3.5.3.3 + - + * - LDBL_MANT_DIG + - |check| + - 5.3.5.3.3 + - + * - LDBL_MAX + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - LDBL_MAX_10_EXP + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - LDBL_MAX_EXP + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - LDBL_MIN + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - LDBL_MIN_10_EXP + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - LDBL_MIN_EXP + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - LDBL_NORM_MAX + - + - 5.3.5.3.3 + - + * - LDBL_SNAN + - + - 5.3.5.3.3 + - + * - LDBL_TRUE_MIN + - |check| + - 5.3.5.3.3 + - `POSIX.1-2024 `__ + * - NAN + - + - 5.3.5.3.3 + - + * - __STDC_VERSION_FLOAT_H__ + - + - 7.7 + - + diff --git a/libc/docs/headers/index.rst b/libc/docs/headers/index.rst new file mode 100644 index 0000000000000..07ab6dd9b2674 --- /dev/null +++ b/libc/docs/headers/index.rst @@ -0,0 +1,30 @@ +Implementation Status +===================== + +.. toctree:: + :maxdepth: 1 + + arpa/inet + assert + complex + ctype + errno + fenv + float + inttypes + locale + math/index.rst + search + setjmp + signal + stdbit + stdio + stdlib + string + strings + sys/mman + threads + time + uchar + wchar + wctype diff --git a/libc/docs/headers/inttypes.rst b/libc/docs/headers/inttypes.rst new file mode 100644 index 0000000000000..9269b40f242a6 --- /dev/null +++ b/libc/docs/headers/inttypes.rst @@ -0,0 +1,42 @@ +.. include:: ../check.rst + +========== +inttypes.h +========== + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX Docs + * - imaxabs + - |check| + - 7.8.2.1 + - `POSIX.1-2024 `__ + * - imaxdiv + - |check| + - 7.8.2.2 + - `POSIX.1-2024 `__ + * - strtoimax + - |check| + - 7.8.2.3 + - `POSIX.1-2024 `__ + * - strtoumax + - |check| + - 7.8.2.3 + - `POSIX.1-2024 `__ + * - wcstoimax + - + - 7.8.2.4 + - `POSIX.1-2024 `__ + * - wcstoumax + - + - 7.8.2.4 + - `POSIX.1-2024 `__ diff --git a/libc/docs/headers/locale.rst b/libc/docs/headers/locale.rst new file mode 100644 index 0000000000000..c97d1f63b1f0c --- /dev/null +++ b/libc/docs/headers/locale.rst @@ -0,0 +1,83 @@ +.. include:: ../check.rst + +======== +locale.h +======== + +Macros +====== + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Macro + - Implemented + - C23 Standard Section + - POSIX Docs + * - LC_ALL + - |check| + - 7.11 + - `POSIX.1-2024 `__ + * - LC_COLLATE + - |check| + - 7.11 + - `POSIX.1-2024 `__ + * - LC_CTYPE + - |check| + - 7.11 + - `POSIX.1-2024 `__ + * - LC_MONETARY + - |check| + - 7.11 + - `POSIX.1-2024 `__ + * - LC_NUMERIC + - |check| + - 7.11 + - `POSIX.1-2024 `__ + * - LC_TIME + - |check| + - 7.11 + - `POSIX.1-2024 `__ + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX Docs + * - duplocale + - |check| + - + - `POSIX.1-2024 `__ + * - freelocale + - |check| + - + - `POSIX.1-2024 `__ + * - getlocalename_l + - + - + - `POSIX.1-2024 `__ + * - localeconv + - |check| + - 7.11.2.1 + - `POSIX.1-2024 `__ + * - newlocale + - |check| + - + - `POSIX.1-2024 `__ + * - setlocale + - |check| + - 7.11.1.1 + - `POSIX.1-2024 `__ + * - uselocale + - |check| + - + - `POSIX.1-2024 `__ diff --git a/libc/docs/math/index.rst b/libc/docs/headers/math/index.rst similarity index 99% rename from libc/docs/math/index.rst rename to libc/docs/headers/math/index.rst index 4934e93ccb164..2808165ad539b 100644 --- a/libc/docs/math/index.rst +++ b/libc/docs/headers/math/index.rst @@ -1,10 +1,10 @@ .. _math: -============== -Math Functions -============== +====== +math.h +====== -.. include:: ../check.rst +.. include:: ../../check.rst .. raw:: html @@ -276,7 +276,7 @@ Higher Math Functions +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | compoundn | | | | | | 7.12.7.2 | F.10.4.2 | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ -| cos | |check| | |check| | | | | 7.12.4.5 | F.10.1.5 | +| cos | |check| | |check| | | |check| | | 7.12.4.5 | F.10.1.5 | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ | cosh | |check| | | | |check| | | 7.12.5.4 | F.10.2.4 | +-----------+------------------+-----------------+------------------------+----------------------+------------------------+------------------------+----------------------------+ diff --git a/libc/docs/math/log.rst b/libc/docs/headers/math/log.rst similarity index 100% rename from libc/docs/math/log.rst rename to libc/docs/headers/math/log.rst diff --git a/libc/docs/math/stdfix.rst b/libc/docs/headers/math/stdfix.rst similarity index 99% rename from libc/docs/math/stdfix.rst rename to libc/docs/headers/math/stdfix.rst index d8dcb0cfa4c52..58052f000995c 100644 --- a/libc/docs/math/stdfix.rst +++ b/libc/docs/headers/math/stdfix.rst @@ -2,7 +2,7 @@ StdFix Functions ================ -.. include:: ../check.rst +.. include:: ../../check.rst Standards and Goals ------------------- diff --git a/libc/docs/libc_search.rst b/libc/docs/headers/search.rst similarity index 95% rename from libc/docs/libc_search.rst rename to libc/docs/headers/search.rst index 774622d1e66c3..51832e9bdc2ed 100644 --- a/libc/docs/libc_search.rst +++ b/libc/docs/headers/search.rst @@ -1,8 +1,8 @@ -============= -Search Tables -============= +======== +search.h +======== -.. include:: check.rst +.. include:: ../check.rst --------------- Source Location diff --git a/libc/docs/setjmp.rst b/libc/docs/headers/setjmp.rst similarity index 82% rename from libc/docs/setjmp.rst rename to libc/docs/headers/setjmp.rst index dd7e0aca3b9cd..b0091134f1a6b 100644 --- a/libc/docs/setjmp.rst +++ b/libc/docs/headers/setjmp.rst @@ -1,4 +1,4 @@ -.. include:: check.rst +.. include:: ../check.rst ======== setjmp.h @@ -15,7 +15,7 @@ Macros * - Macro - Implemented - C23 Standard Section - - POSIX.1-2017 Standard Section + - POSIX.1-2024 Standard Section * - __STDC_VERSION_SETJMP_H__ - - 7.13.2 @@ -32,7 +32,7 @@ Functions * - Function - Implemented - C23 Standard Section - - POSIX.1-2017 Standard Section + - POSIX.1-2024 Standard Section * - longjmp - |check| - 7.13.2.1 diff --git a/libc/docs/headers/signal.rst b/libc/docs/headers/signal.rst new file mode 100644 index 0000000000000..4f51f611c9fe7 --- /dev/null +++ b/libc/docs/headers/signal.rst @@ -0,0 +1,207 @@ +.. include:: ../check.rst + +======== +signal.h +======== + +Macros +====== + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Macro + - Implemented + - C23 Standard Section + - POSIX Docs + * - SIGABRT + - |check| + - 7.14.3 + - `POSIX.1-2024 `__ + * - SIGALRM + - |check| + - + - `POSIX.1-2024 `__ + * - SIGBUS + - |check| + - + - `POSIX.1-2024 `__ + * - SIGCHLD + - |check| + - + - `POSIX.1-2024 `__ + * - SIGCONT + - |check| + - + - `POSIX.1-2024 `__ + * - SIGFPE + - |check| + - 7.14.3 + - `POSIX.1-2024 `__ + * - SIGHUP + - |check| + - + - `POSIX.1-2024 `__ + * - SIGILL + - |check| + - 7.14.3 + - `POSIX.1-2024 `__ + * - SIGINT + - |check| + - 7.14.3 + - `POSIX.1-2024 `__ + * - SIGKILL + - |check| + - + - `POSIX.1-2024 `__ + * - SIGPIPE + - |check| + - + - `POSIX.1-2024 `__ + * - SIGPOLL + - |check| + - + - `POSIX.1-2024 `__ + * - SIGPROF + - |check| + - + - `POSIX.1-2024 `__ + * - SIGQUIT + - |check| + - + - `POSIX.1-2024 `__ + * - SIGRTMAX + - |check| + - + - `POSIX.1-2024 `__ + * - SIGRTMIN + - |check| + - + - `POSIX.1-2024 `__ + * - SIGSEGV + - |check| + - 7.14.3 + - `POSIX.1-2024 `__ + * - SIGSTOP + - |check| + - + - `POSIX.1-2024 `__ + * - SIGSYS + - |check| + - + - `POSIX.1-2024 `__ + * - SIGTERM + - |check| + - 7.14.3 + - `POSIX.1-2024 `__ + * - SIGTRAP + - |check| + - + - `POSIX.1-2024 `__ + * - SIGTSTP + - |check| + - + - `POSIX.1-2024 `__ + * - SIGTTIN + - |check| + - + - `POSIX.1-2024 `__ + * - SIGTTOU + - |check| + - + - `POSIX.1-2024 `__ + * - SIGURG + - |check| + - + - `POSIX.1-2024 `__ + * - SIGUSR1 + - |check| + - + - `POSIX.1-2024 `__ + * - SIGUSR2 + - |check| + - + - `POSIX.1-2024 `__ + * - SIGVTALRM + - |check| + - + - `POSIX.1-2024 `__ + * - SIGXCPU + - |check| + - + - `POSIX.1-2024 `__ + * - SIGXFSZ + - |check| + - + - `POSIX.1-2024 `__ + * - SIG_DFL + - |check| + - 7.14.3 + - `POSIX.1-2024 `__ + * - SIG_ERR + - |check| + - 7.14.3 + - `POSIX.1-2024 `__ + * - SIG_HOLD + - + - + - `POSIX.1-2024 `__ + * - SIG_IGN + - |check| + - 7.14.3 + - `POSIX.1-2024 `__ + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX Docs + * - kill + - |check| + - + - `POSIX.1-2024 `__ + * - raise + - |check| + - 7.14.2.1 + - `POSIX.1-2024 `__ + * - sigaction + - |check| + - + - `POSIX.1-2024 `__ + * - sigaddset + - |check| + - + - `POSIX.1-2024 `__ + * - sigaltstack + - |check| + - + - `POSIX.1-2024 `__ + * - sigdelset + - |check| + - + - `POSIX.1-2024 `__ + * - sigemptyset + - |check| + - + - `POSIX.1-2024 `__ + * - sigfillset + - |check| + - + - `POSIX.1-2024 `__ + * - signal + - |check| + - 7.14.1.1 + - `POSIX.1-2024 `__ + * - sigprocmask + - |check| + - + - `POSIX.1-2024 `__ diff --git a/libc/docs/stdbit.rst b/libc/docs/headers/stdbit.rst similarity index 98% rename from libc/docs/stdbit.rst rename to libc/docs/headers/stdbit.rst index e6b82bb77a14a..0484d951e19c6 100644 --- a/libc/docs/stdbit.rst +++ b/libc/docs/headers/stdbit.rst @@ -1,4 +1,4 @@ -.. include:: check.rst +.. include:: ../check.rst ======== stdbit.h @@ -15,7 +15,7 @@ Macros * - Macro - Implemented - C23 Standard Section - - POSIX.1-2017 Standard Section + - POSIX.1-2024 Standard Section * - __STDC_ENDIAN_BIG__ - |check| - 7.18.2.2 @@ -100,7 +100,7 @@ Functions * - Function - Implemented - C23 Standard Section - - POSIX.1-2017 Standard Section + - POSIX.1-2024 Standard Section * - stdc_bit_ceil_uc - |check| - 7.18.16 diff --git a/libc/docs/stdio.rst b/libc/docs/headers/stdio.rst similarity index 96% rename from libc/docs/stdio.rst rename to libc/docs/headers/stdio.rst index d17821562c255..3cd355529d400 100644 --- a/libc/docs/stdio.rst +++ b/libc/docs/headers/stdio.rst @@ -1,8 +1,8 @@ -=============== -StdIO Functions -=============== +======= +stdio.h +======= -.. include:: check.rst +.. include:: ../check.rst --------------- Source location diff --git a/libc/docs/headers/stdlib.rst b/libc/docs/headers/stdlib.rst new file mode 100644 index 0000000000000..4151f2934c940 --- /dev/null +++ b/libc/docs/headers/stdlib.rst @@ -0,0 +1,255 @@ +.. include:: ../check.rst + +======== +stdlib.h +======== + +Macros +====== + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Macro + - Implemented + - C23 Standard Section + - POSIX Docs + * - EXIT_FAILURE + - |check| + - 7.24 + - `POSIX.1-2024 `__ + * - EXIT_SUCCESS + - |check| + - 7.24 + - `POSIX.1-2024 `__ + * - MB_CUR_MAX + - |check| + - 7.24 + - `POSIX.1-2024 `__ + * - RAND_MAX + - |check| + - 7.24 + - `POSIX.1-2024 `__ + * - __STDC_VERSION_STDLIB_H__ + - + - 7.24 + - + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX Docs + * - _Exit + - |check| + - 7.24.4.5 + - `POSIX.1-2024 `__ + * - abort + - |check| + - 7.24.4.1 + - `POSIX.1-2024 `__ + * - abs + - |check| + - 7.24.6.1 + - `POSIX.1-2024 `__ + * - aligned_alloc + - |check| + - 7.24.3.1 + - `POSIX.1-2024 `__ + * - at_quick_exit + - |check| + - 7.24.4.3 + - `POSIX.1-2024 `__ + * - atexit + - |check| + - 7.24.4.2 + - `POSIX.1-2024 `__ + * - atof + - |check| + - 7.24.1.1 + - `POSIX.1-2024 `__ + * - atoi + - |check| + - 7.24.1.2 + - `POSIX.1-2024 `__ + * - atol + - |check| + - 7.24.1.2 + - `POSIX.1-2024 `__ + * - atoll + - |check| + - 7.24.1.2 + - `POSIX.1-2024 `__ + * - bsearch + - |check| + - 7.24.5.1 + - `POSIX.1-2024 `__ + * - calloc + - |check| + - 7.24.3.2 + - `POSIX.1-2024 `__ + * - div + - |check| + - 7.24.6.2 + - `POSIX.1-2024 `__ + * - exit + - |check| + - 7.24.4.4 + - `POSIX.1-2024 `__ + * - free + - |check| + - 7.24.3.3 + - `POSIX.1-2024 `__ + * - free_aligned_sized + - + - 7.24.3.5 + - + * - free_sized + - + - 7.24.3.4 + - + * - getenv + - |check| + - 7.24.4.6 + - `POSIX.1-2024 `__ + * - labs + - |check| + - 7.24.6.1 + - `POSIX.1-2024 `__ + * - ldiv + - |check| + - 7.24.6.2 + - `POSIX.1-2024 `__ + * - llabs + - |check| + - 7.24.6.1 + - `POSIX.1-2024 `__ + * - lldiv + - |check| + - 7.24.6.2 + - `POSIX.1-2024 `__ + * - malloc + - |check| + - 7.24.3.6 + - `POSIX.1-2024 `__ + * - mblen + - + - 7.24.7.1 + - `POSIX.1-2024 `__ + * - mbstowcs + - + - 7.24.8.1 + - `POSIX.1-2024 `__ + * - mbtowc + - + - 7.24.7.2 + - `POSIX.1-2024 `__ + * - memalignment + - + - 7.24.9.1 + - + * - qsort + - |check| + - 7.24.5.2 + - `POSIX.1-2024 `__ + * - quick_exit + - |check| + - 7.24.4.7 + - `POSIX.1-2024 `__ + * - rand + - |check| + - 7.24.2.1 + - `POSIX.1-2024 `__ + * - realloc + - |check| + - 7.24.3.7 + - `POSIX.1-2024 `__ + * - srand + - |check| + - 7.24.2.2 + - `POSIX.1-2024 `__ + * - strfromd + - |check| + - 7.24.1.3 + - + * - strfromd128 + - + - 7.24.1.4 + - + * - strfromd32 + - + - 7.24.1.4 + - + * - strfromd64 + - + - 7.24.1.4 + - + * - strfromf + - |check| + - 7.24.1.3 + - + * - strfroml + - |check| + - 7.24.1.3 + - + * - strtod + - |check| + - 7.24.1.5 + - `POSIX.1-2024 `__ + * - strtod128 + - + - 7.24.1.6 + - + * - strtod32 + - + - 7.24.1.6 + - + * - strtod64 + - + - 7.24.1.6 + - + * - strtof + - |check| + - 7.24.1.5 + - `POSIX.1-2024 `__ + * - strtol + - |check| + - 7.24.1.7 + - `POSIX.1-2024 `__ + * - strtold + - |check| + - 7.24.1.5 + - `POSIX.1-2024 `__ + * - strtoll + - |check| + - 7.24.1.7 + - `POSIX.1-2024 `__ + * - strtoul + - |check| + - 7.24.1.7 + - `POSIX.1-2024 `__ + * - strtoull + - |check| + - 7.24.1.7 + - `POSIX.1-2024 `__ + * - system + - |check| + - 7.24.4.8 + - `POSIX.1-2024 `__ + * - wcstombs + - + - 7.24.8.2 + - `POSIX.1-2024 `__ + * - wctomb + - + - 7.24.7.3 + - `POSIX.1-2024 `__ diff --git a/libc/docs/headers/string.rst b/libc/docs/headers/string.rst new file mode 100644 index 0000000000000..2665ed8ca17e6 --- /dev/null +++ b/libc/docs/headers/string.rst @@ -0,0 +1,163 @@ +.. include:: ../check.rst + +======== +string.h +======== + +Macros +====== + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Macro + - Implemented + - C23 Standard Section + - POSIX Docs + * - __STDC_VERSION_STRING_H__ + - + - 7.26.1 + - + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX Docs + * - memccpy + - |check| + - 7.26.2.2 + - `POSIX.1-2024 `__ + * - memchr + - |check| + - 7.26.5.2 + - `POSIX.1-2024 `__ + * - memcmp + - |check| + - 7.26.4.1 + - `POSIX.1-2024 `__ + * - memcpy + - |check| + - 7.26.2.1 + - `POSIX.1-2024 `__ + * - memmove + - |check| + - 7.26.2.3 + - `POSIX.1-2024 `__ + * - mempcpy + - |check| + - TODO: glibc extension + - + * - memset + - |check| + - 7.26.6.1 + - `POSIX.1-2024 `__ + * - memset_explicit + - |check| + - 7.26.6.2 + - + * - stpcpy + - |check| + - + - `POSIX.1-2024 `__ + * - stpncpy + - |check| + - + - `POSIX.1-2024 `__ + * - strcat + - |check| + - 7.26.3.1 + - `POSIX.1-2024 `__ + * - strchr + - |check| + - 7.26.5.3 + - `POSIX.1-2024 `__ + * - strcmp + - |check| + - 7.26.4.2 + - `POSIX.1-2024 `__ + * - strcoll + - |check| + - 7.26.4.3 + - `POSIX.1-2024 `__ + * - strcoll_l + - |check| + - + - `POSIX.1-2024 `__ + * - strcpy + - |check| + - 7.26.2.4 + - `POSIX.1-2024 `__ + * - strcspn + - |check| + - 7.26.5.4 + - `POSIX.1-2024 `__ + * - strdup + - |check| + - 7.26.2.6 + - `POSIX.1-2024 `__ + * - strerror + - |check| + - 7.26.6.3 + - `POSIX.1-2024 `__ + * - strlen + - |check| + - 7.26.6.4 + - `POSIX.1-2024 `__ + * - strncat + - |check| + - 7.26.3.2 + - `POSIX.1-2024 `__ + * - strncmp + - |check| + - 7.26.4.4 + - `POSIX.1-2024 `__ + * - strncpy + - |check| + - 7.26.2.5 + - `POSIX.1-2024 `__ + * - strndup + - |check| + - 7.26.2.7 + - `POSIX.1-2024 `__ + * - strpbrk + - |check| + - 7.26.5.5 + - `POSIX.1-2024 `__ + * - strrchr + - |check| + - 7.26.5.6 + - `POSIX.1-2024 `__ + * - strspn + - |check| + - 7.26.5.7 + - `POSIX.1-2024 `__ + * - strstr + - |check| + - 7.26.5.8 + - `POSIX.1-2024 `__ + * - strtok + - |check| + - 7.26.5.9 + - `POSIX.1-2024 `__ + * - strtok_r + - |check| + - + - `POSIX.1-2024 `__ + * - strxfrm + - |check| + - 7.26.4.5 + - `POSIX.1-2024 `__ + * - strxfrm_l + - |check| + - + - `POSIX.1-2024 `__ diff --git a/libc/docs/headers/strings.rst b/libc/docs/headers/strings.rst new file mode 100644 index 0000000000000..effd667cd5219 --- /dev/null +++ b/libc/docs/headers/strings.rst @@ -0,0 +1,66 @@ +.. include:: ../check.rst + +========= +strings.h +========= + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX Docs + * - bcmp + - |check| + - + - `removed in POSIX.1-2008 `__ + * - bcopy + - |check| + - + - `removed in POSIX.1-2008 `__ + * - bzero + - |check| + - + - `removed in POSIX.1-2008 `__ + * - ffs + - + - + - `POSIX.1-2024 `__ + * - ffsl + - + - + - `POSIX.1-2024 `__ + * - ffsll + - + - + - `POSIX.1-2024 `__ + * - index + - |check| + - + - `removed in POSIX.1-2008 `__ + * - rindex + - |check| + - + - `removed in POSIX.1-2008 `__ + * - strcasecmp + - |check| + - + - `POSIX.1-2024 `__ + * - strcasecmp_l + - + - + - `POSIX.1-2024 `__ + * - strncasecmp + - |check| + - + - `POSIX.1-2024 `__ + * - strncasecmp_l + - + - + - `POSIX.1-2024 `__ diff --git a/libc/docs/headers/sys/mman.rst b/libc/docs/headers/sys/mman.rst new file mode 100644 index 0000000000000..e3404205c07ac --- /dev/null +++ b/libc/docs/headers/sys/mman.rst @@ -0,0 +1,179 @@ +.. include:: ../../check.rst + +========== +sys/mman.h +========== + +Macros +====== + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Macro + - Implemented + - C23 Standard Section + - POSIX.1-2024 Standard Section + * - MAP_ANON + - + - + - + * - MAP_ANONYMOUS + - + - + - + * - MAP_FAILED + - |check| + - + - + * - MAP_FIXED + - + - + - + * - MAP_PRIVATE + - + - + - + * - MAP_SHARED + - + - + - + * - MCL_CURRENT + - + - + - + * - MCL_FUTURE + - + - + - + * - MS_ASYNC + - + - + - + * - MS_INVALIDATE + - + - + - + * - MS_SYNC + - + - + - + * - POSIX_MADV_DONTNEED + - |check| + - + - + * - POSIX_MADV_NORMAL + - |check| + - + - + * - POSIX_MADV_RANDOM + - |check| + - + - + * - POSIX_MADV_SEQUENTIAL + - |check| + - + - + * - POSIX_MADV_WILLNEED + - |check| + - + - + * - POSIX_TYPED_MEM_ALLOCATE + - + - + - + * - POSIX_TYPED_MEM_ALLOCATE_CONTIG + - + - + - + * - POSIX_TYPED_MEM_MAP_ALLOCATABLE + - + - + - + * - PROT_EXEC + - + - + - + * - PROT_NONE + - + - + - + * - PROT_READ + - + - + - + * - PROT_WRITE + - + - + - + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX.1-2024 Standard Section + * - mlock + - |check| + - + - + * - mlockall + - |check| + - + - + * - mmap + - |check| + - + - + * - mprotect + - |check| + - + - + * - msync + - |check| + - + - + * - munlock + - |check| + - + - + * - munlockall + - |check| + - + - + * - munmap + - |check| + - + - + * - posix_madvise + - |check| + - + - + * - posix_mem_offset + - + - + - + * - posix_typed_mem_get_info + - + - + - + * - posix_typed_mem_open + - + - + - + * - shm_open + - |check| + - + - + * - shm_unlink + - |check| + - + - diff --git a/libc/docs/headers/threads.rst b/libc/docs/headers/threads.rst new file mode 100644 index 0000000000000..c2837b8c3591c --- /dev/null +++ b/libc/docs/headers/threads.rst @@ -0,0 +1,147 @@ +.. include:: ../check.rst + +========= +threads.h +========= + +Macros +====== + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Macro + - Implemented + - C23 Standard Section + - POSIX Docs + * - ONCE_FLAG_INIT + - + - 7.28.1 + - `POSIX.1-2024 `__ + * - TSS_DTOR_ITERATIONS + - + - 7.28.1 + - `POSIX.1-2024 `__ + * - __STDC_NO_THREADS__ + - + - 7.28.1 + - + * - thread_local + - + - + - `POSIX.1-2024 `__ + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX Docs + * - call_once + - |check| + - 7.28.2.1 + - `POSIX.1-2024 `__ + * - cnd_broadcast + - |check| + - 7.28.3.1 + - `POSIX.1-2024 `__ + * - cnd_destroy + - |check| + - 7.28.3.2 + - `POSIX.1-2024 `__ + * - cnd_init + - |check| + - 7.28.3.3 + - `POSIX.1-2024 `__ + * - cnd_signal + - |check| + - 7.28.3.4 + - `POSIX.1-2024 `__ + * - cnd_timedwait + - + - 7.28.3.5 + - `POSIX.1-2024 `__ + * - cnd_wait + - |check| + - 7.28.3.6 + - `POSIX.1-2024 `__ + * - mtx_destroy + - |check| + - 7.28.4.2 + - `POSIX.1-2024 `__ + * - mtx_init + - |check| + - 7.28.4.3 + - `POSIX.1-2024 `__ + * - mtx_lock + - |check| + - 7.28.4.4 + - `POSIX.1-2024 `__ + * - mtx_timedlock + - + - 7.28.4.5 + - `POSIX.1-2024 `__ + * - mtx_trylock + - + - 7.28.4.6 + - `POSIX.1-2024 `__ + * - mtx_unlock + - |check| + - 7.28.4.7 + - `POSIX.1-2024 `__ + * - thrd_create + - |check| + - 7.28.5.1 + - `POSIX.1-2024 `__ + * - thrd_current + - |check| + - 7.28.5.2 + - `POSIX.1-2024 `__ + * - thrd_detach + - |check| + - 7.28.5.3 + - `POSIX.1-2024 `__ + * - thrd_equal + - |check| + - 7.28.5.4 + - `POSIX.1-2024 `__ + * - thrd_exit + - |check| + - 7.28.5.5 + - `POSIX.1-2024 `__ + * - thrd_join + - |check| + - 7.28.5.6 + - `POSIX.1-2024 `__ + * - thrd_sleep + - + - 7.28.5.7 + - `POSIX.1-2024 `__ + * - thrd_yield + - + - 7.28.5.8 + - `POSIX.1-2024 `__ + * - tss_create + - |check| + - 7.28.6.1 + - `POSIX.1-2024 `__ + * - tss_delete + - |check| + - 7.28.6.2 + - `POSIX.1-2024 `__ + * - tss_get + - |check| + - 7.28.6.3 + - `POSIX.1-2024 `__ + * - tss_set + - |check| + - 7.28.6.4 + - `POSIX.1-2024 `__ diff --git a/libc/docs/date_and_time.rst b/libc/docs/headers/time.rst similarity index 99% rename from libc/docs/date_and_time.rst rename to libc/docs/headers/time.rst index b745a3b416f80..de82d80a2bec4 100644 --- a/libc/docs/date_and_time.rst +++ b/libc/docs/headers/time.rst @@ -1,8 +1,8 @@ -======================= -Date and Time Functions -======================= +====== +time.h +====== -.. include:: check.rst +.. include:: ../check.rst --------------- Source location diff --git a/libc/docs/headers/uchar.rst b/libc/docs/headers/uchar.rst new file mode 100644 index 0000000000000..abb684bf9ae0e --- /dev/null +++ b/libc/docs/headers/uchar.rst @@ -0,0 +1,59 @@ +.. include:: ../check.rst + +======= +uchar.h +======= + +Macros +====== + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Macro + - Implemented + - C23 Standard Section + - POSIX Docs + * - __STDC_VERSION_UCHAR_H__ + - + - 7.30.1 + - + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX Docs + * - c16rtomb + - + - 7.30.2.5 + - `POSIX.1-2024 `__ + * - c32rtomb + - + - 7.30.2.7 + - `POSIX.1-2024 `__ + * - c8rtomb + - + - 7.30.2.3 + - + * - mbrtoc16 + - + - 7.30.2.4 + - `POSIX.1-2024 `__ + * - mbrtoc32 + - + - 7.30.2.6 + - `POSIX.1-2024 `__ + * - mbrtoc8 + - + - 7.30.2.2 + - diff --git a/libc/docs/headers/wchar.rst b/libc/docs/headers/wchar.rst new file mode 100644 index 0000000000000..89a1e7b3fe660 --- /dev/null +++ b/libc/docs/headers/wchar.rst @@ -0,0 +1,287 @@ +.. include:: ../check.rst + +======= +wchar.h +======= + +Macros +====== + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Macro + - Implemented + - C23 Standard Section + - POSIX Docs + * - WEOF + - |check| + - 7.31.1 + - + * - __STDC_VERSION_WCHAR_H__ + - + - 7.31.1 + - + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX Docs + * - btowc + - |check| + - 7.31.6.2.1 + - + * - fgetwc + - + - 7.31.3.1 + - + * - fgetws + - + - 7.31.3.2 + - + * - fputwc + - + - 7.31.3.3 + - + * - fputws + - + - 7.31.3.4 + - + * - fwide + - + - 7.31.3.5 + - + * - fwprintf + - + - 7.31.2.2 + - + * - fwscanf + - + - 7.31.2.3 + - + * - getwc + - + - 7.31.3.6 + - + * - getwchar + - + - 7.31.3.7 + - + * - mbrlen + - + - 7.31.6.4.2 + - + * - mbrtowc + - + - 7.31.6.4.3 + - + * - mbsinit + - + - 7.31.6.3.1 + - + * - mbsrtowcs + - + - 7.31.6.5.2 + - + * - putwc + - + - 7.31.3.8 + - + * - putwchar + - + - 7.31.3.9 + - + * - swprintf + - + - 7.31.2.4 + - + * - swscanf + - + - 7.31.2.5 + - + * - ungetwc + - + - 7.31.3.10 + - + * - vfwprintf + - + - 7.31.2.6 + - + * - vfwscanf + - + - 7.31.2.7 + - + * - vswprintf + - + - 7.31.2.8 + - + * - vswscanf + - + - 7.31.2.9 + - + * - vwprintf + - + - 7.31.2.10 + - + * - vwscanf + - + - 7.31.2.11 + - + * - wcrtomb + - + - 7.31.6.4.4 + - + * - wcscat + - + - 7.31.4.4.1 + - + * - wcschr + - + - 7.31.4.6.2 + - + * - wcscmp + - + - 7.31.4.5.2 + - + * - wcscoll + - + - 7.31.4.5.3 + - + * - wcscpy + - + - 7.31.4.3.1 + - + * - wcscspn + - + - 7.31.4.6.3 + - + * - wcsftime + - + - 7.31.5.1 + - + * - wcslen + - + - 7.31.4.7.1 + - + * - wcsncat + - + - 7.31.4.4.2 + - + * - wcsncmp + - + - 7.31.4.5.4 + - + * - wcsncpy + - + - 7.31.4.3.2 + - + * - wcspbrk + - + - 7.31.4.6.4 + - + * - wcsrchr + - + - 7.31.4.6.5 + - + * - wcsrtombs + - + - 7.31.6.5.3 + - + * - wcsspn + - + - 7.31.4.6.6 + - + * - wcsstr + - + - 7.31.4.6.7 + - + * - wcstod + - + - 7.31.4.2.2 + - + * - wcstod128 + - + - 7.31.4.2.3 + - + * - wcstod32 + - + - 7.31.4.2.3 + - + * - wcstod64 + - + - 7.31.4.2.3 + - + * - wcstof + - + - 7.31.4.2.2 + - + * - wcstok + - + - 7.31.4.6.8 + - + * - wcstol + - + - 7.31.4.2.4 + - + * - wcstold + - + - 7.31.4.2.2 + - + * - wcstoll + - + - 7.31.4.2.4 + - + * - wcstoul + - + - 7.31.4.2.4 + - + * - wcstoull + - + - 7.31.4.2.4 + - + * - wcsxfrm + - + - 7.31.4.5.5 + - + * - wctob + - |check| + - 7.31.6.2.2 + - + * - wmemchr + - + - 7.31.4.6.9 + - + * - wmemcmp + - + - 7.31.4.5.6 + - + * - wmemcpy + - + - 7.31.4.3.3 + - + * - wmemmove + - + - 7.31.4.3.4 + - + * - wmemset + - + - 7.31.4.7.2 + - + * - wprintf + - + - 7.31.2.12 + - + * - wscanf + - + - 7.31.2.13 + - diff --git a/libc/docs/headers/wctype.rst b/libc/docs/headers/wctype.rst new file mode 100644 index 0000000000000..076db04f183e9 --- /dev/null +++ b/libc/docs/headers/wctype.rst @@ -0,0 +1,86 @@ +.. include:: ../check.rst + +======== +wctype.h +======== + +Functions +========= + +.. list-table:: + :widths: auto + :align: center + :header-rows: 1 + + * - Function + - Implemented + - C23 Standard Section + - POSIX Docs + * - iswalnum + - + - 7.32.2.1.1 + - + * - iswalpha + - + - 7.32.2.1.2 + - + * - iswblank + - + - 7.32.2.1.4 + - + * - iswctype + - + - 7.32.2.2.1 + - + * - iswdigit + - + - 7.32.2.1.5 + - + * - iswgraph + - + - 7.32.2.1.6 + - + * - iswlower + - + - 7.32.2.1.7 + - + * - iswprint + - + - 7.32.2.1.8 + - + * - iswpunct + - + - 7.32.2.1.9 + - + * - iswspace + - + - 7.32.2.1.10 + - + * - iswupper + - + - 7.32.2.1.11 + - + * - iswxdigit + - + - 7.32.2.1.12 + - + * - towctrans + - + - 7.32.3.2.1 + - + * - towlower + - + - 7.32.3.1.1 + - + * - towupper + - + - 7.32.3.1.2 + - + * - wctrans + - + - 7.32.3.2.2 + - + * - wctype + - + - 7.32.2.2.2 + - diff --git a/libc/docs/index.rst b/libc/docs/index.rst index 6f759aa215b62..0cbf75f5e0ef2 100644 --- a/libc/docs/index.rst +++ b/libc/docs/index.rst @@ -2,18 +2,24 @@ The LLVM C Library ================== +.. warning:: + LLVM-libc is not yet ABI stable; currently only static linking is supported. + LLVM-libc developers retain the right to modify the ABI of types used + throughout the library. Another libc should be preferred if ABI stability is + a requirement. + .. note:: LLVM-libc is not fully complete right now. Some programs may fail to build due - to missing functions (especially C++ ones). If you would like to help us - finish LLVM-libc, check out "Contributing to the libc project" in the sidebar - or ask on discord. + to missing functions. If you would like to help us finish LLVM-libc, check + out "`Contributing to the libc project `__" in the sidebar + or ask on `discord `__. Introduction ============ LLVM-libc aspires to a unique place in the software ecosystem. The goals are: -- Fully compliant with current C standards (C17 and upcoming C2x) and POSIX. +- Fully compliant with current C23 and POSIX.1-2024 standards. - Easily decomposed and embedded: Supplement or replace system C library functionality easily. This is useful to get consistent math precision across systems, or updated memory operations for newer microarchitectures. These @@ -27,25 +33,8 @@ LLVM-libc aspires to a unique place in the software ecosystem. The goals are: libc functions. - A complete testsuite that tests both the public interface and internal algorithms. -- `Fuzzing`__ - -.. __: https://github.com/llvm/llvm-project/tree/main/libc/fuzzing - -Platform Support -================ +- `Fuzzing `__ -Most development is currently targeting Linux on x86_64, aarch64, arm, and -RISC-V. Embedded/baremetal targets are supported on arm and RISC-V, and Windows -and MacOS have limited support (may be broken). The Fuchsia platform is -slowly replacing functions from its bundled libc with functions from this -project. - -ABI Compatibility -================= - -The libc is written to be ABI independent. Interfaces are generated using -headergen, so supporting arbitrary ABIs is possible. In it's initial -stages there is no ABI stability in any form. .. toctree:: :hidden: @@ -63,20 +52,17 @@ stages there is no ABI stability in any form. :maxdepth: 1 :caption: Status - compiler_support - date_and_time - math/index.rst - strings - stdio - stdbit - fenv - libc_search + headers/index.rst c23 - ctype - complex - signal - threads - setjmp + +.. toctree:: + :hidden: + :maxdepth: 1 + :caption: Support + + arch_support + platform_support + compiler_support .. toctree:: :hidden: diff --git a/libc/docs/platform_support.rst b/libc/docs/platform_support.rst new file mode 100644 index 0000000000000..2ce3d7282b304 --- /dev/null +++ b/libc/docs/platform_support.rst @@ -0,0 +1,22 @@ +Platform Support +================ + +Development is currently mostly focused on Linux. MacOS and Windows has +partial support, but has bitrot and isn't being tested continuously. + +LLVM-libc is currently being integrated into Android and Fuchsia operating +systems via `overlay mode `__. + +For Linux, we support kernel versions as listed on +`kernel.org `_, including ``longterm`` (not past EOL +date), ``stable``, and ``mainline`` versions. We actively adopt new features +from ``linux-next``. + +For Windows, we plan to support products within their lifecycle. Please refer to +`Search Product and Services Lifecycle Information `_ for more information. + +LLVM-libc does not guarantee backward compatibility with operating systems that +have reached their EOL. Compatibility patches for obsolete operating systems +will not be accepted. + +For GPU, reference `our GPU docs `__. diff --git a/libc/docs/signal.rst b/libc/docs/signal.rst deleted file mode 100644 index e12f67b0c61c0..0000000000000 --- a/libc/docs/signal.rst +++ /dev/null @@ -1,207 +0,0 @@ -.. include:: check.rst - -======== -signal.h -======== - -Macros -====== - -.. list-table:: - :widths: auto - :align: center - :header-rows: 1 - - * - Macro - - Implemented - - C23 Standard Section - - POSIX.1-2017 Standard Section - * - SIGABRT - - |check| - - 7.14.3 - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGALRM - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGBUS - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGCHLD - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGCONT - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGFPE - - |check| - - 7.14.3 - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGHUP - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGILL - - |check| - - 7.14.3 - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGINT - - |check| - - 7.14.3 - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGKILL - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGPIPE - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGPOLL - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGPROF - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGQUIT - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGRTMAX - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGRTMIN - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGSEGV - - |check| - - 7.14.3 - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGSTOP - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGSYS - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGTERM - - |check| - - 7.14.3 - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGTRAP - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGTSTP - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGTTIN - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGTTOU - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGURG - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGUSR1 - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGUSR2 - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGVTALRM - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGXCPU - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIGXFSZ - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIG_DFL - - |check| - - 7.14.3 - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIG_ERR - - |check| - - 7.14.3 - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIG_HOLD - - - - - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - * - SIG_IGN - - |check| - - 7.14.3 - - https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html - -Functions -========= - -.. list-table:: - :widths: auto - :align: center - :header-rows: 1 - - * - Function - - Implemented - - C23 Standard Section - - POSIX.1-2017 Standard Section - * - kill - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html - * - raise - - |check| - - 7.14.2.1 - - https://pubs.opengroup.org/onlinepubs/9699919799/functions/raise.html - * - sigaction - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html - * - sigaddset - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaddset.html - * - sigaltstack - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaltstack.html - * - sigdelset - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigdelset.html - * - sigemptyset - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigemptyset.html - * - sigfillset - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigfillset.html - * - signal - - |check| - - 7.14.1.1 - - https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html - * - sigprocmask - - |check| - - - - https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html diff --git a/libc/docs/strings.rst b/libc/docs/strings.rst deleted file mode 100644 index 427644c407ae8..0000000000000 --- a/libc/docs/strings.rst +++ /dev/null @@ -1,166 +0,0 @@ -================ -String Functions -================ - -.. include:: check.rst - ---------------- -Source location ---------------- - -- The main source for string functions is located at: - ``libc/src/string``. - -- The source for string conversion functions is located at: - ``libc/src/stdlib`` and - ``libc/src/__support``. - -- The tests are located at: - ``libc/test/src/string``, - ``libc/test/src/stdlib``, and - ``libc/test/src/__support`` - respectively. - ---------------------- -Implementation Status ---------------------- - -Primary memory functions -======================== - -.. TODO(gchatelet): add details about the memory functions. - - -============= ========= -Function Name Available -============= ========= -bzero |check| -bcmp |check| -bcopy |check| -memcpy |check| -memset |check| -memcmp |check| -memmove |check| -============= ========= - - -Other Raw Memory Functions -========================== - -============= ========= -Function Name Available -============= ========= -memchr |check| -memrchr |check| -memccpy |check| -mempcpy |check| -============= ========= - -String Memory Functions -======================= - -============= ========= -Function Name Available -============= ========= -stpcpy |check| -stpncpy |check| -strcpy |check| -strncpy |check| -strcat |check| -strncat |check| -strdup |check| -strndup |check| -============= ========= - -String Examination Functions -============================ - -============= ========= -Function Name Available -============= ========= -strlen |check| -strnlen |check| -strcmp |check| -strncmp |check| -strchr |check| -strrchr |check| -strspn |check| -strcspn |check| -strpbrk |check| -strstr |check| -strtok |check| -strtok_r |check| -============= ========= - -String Conversion Functions -============================ - -These functions are not in strings.h, but are still primarily string -functions, and are therefore tracked along with the rest of the string -functions. - -The String to float functions were implemented using the Eisel-Lemire algorithm -(read more about the algorithm here: `The Eisel-Lemire ParseNumberF64 Algorithm -`_). This improved -the performance of string to float and double, and allowed it to complete this -comprehensive test 15% faster than glibc: `Parse Number FXX Test Data -`_. The test was done -with LLVM-libc built on 2022-04-14 and Debian GLibc version 2.33-6. The targets -``libc_str_to_float_comparison_test`` and -``libc_system_str_to_float_comparison_test`` were built and run on the test data -10 times each, skipping the first run since it was an outlier. - - -============= ========= -Function Name Available -============= ========= -atof |check| -atoi |check| -atol |check| -atoll |check| -strtol |check| -strtoll |check| -strtoul |check| -strtoull |check| -strtof |check| -strtod |check| -strtold |check| -strtoimax |check| -strtoumax |check| -============= ========= - -String Error Functions -====================== - -============= ========= -Function Name Available -============= ========= -strerror |check| -strerror_r |check| -============= ========= - -Localized String Functions -========================== - -These functions require locale.h, and will be finished when locale support is -implemented in LLVM-libc. - -============= ========= -Function Name Available -============= ========= -strcoll Partially -strxfrm Partially -============= ========= - ---------------------------- -\_s String Functions ---------------------------- - -Many String functions have an equivalent _s version, which is intended to be -more secure and safe than the previous standard. These functions add runtime -error detection and overflow protection. While they can be seen as an -improvement, adoption remains relatively low among users. In addition, they are -being considered for removal, see -`Field Experience With Annex K — Bounds Checking Interfaces -`_. For these reasons, -there is no ongoing work to implement them. diff --git a/libc/docs/talks.rst b/libc/docs/talks.rst index 7e560964d6aa5..67a5243341b18 100644 --- a/libc/docs/talks.rst +++ b/libc/docs/talks.rst @@ -1,6 +1,45 @@ ===== Talks ===== +---- +2024 +---- +* A C/C++ Toolchain for your GPU - Joseph Huber + + * `slides `__ + * `videos `__ + * `phoronix `__ + +* Modern Embedded Development with LLVM - Petr Hosek + + * `slides `__ + * `videos `__ + +* Using llvm-libc in LLVM Embedded Toolchain for Arm - Peter Smith + + * `slides `__ + * `videos `__ + +* RISC-V Support into LLVM libc - Challenges and Solutions for 32-bit and 64-bit - Mikhail R. Gadelha + + * `slides `__ + * `videos `__ + +* Project Hand-in-Hand - The beginning of a beautiful friendship - Michael Jones & Christopher Di Bella + + * `slides `__ + * `videos `__ + +* LLVM libc math library - Current status and future directions - Tue Ly + + * `slides `__ + * `videos `__ + +* Half-precision in LLVM libc - Nicolas Celik + + * `slides `__ + * `videos `__ + ---- 2023 ---- @@ -8,10 +47,12 @@ Talks * `slides `__ * `video `__ + * The LLVM C Library for GPUs - Joseph Huber * `slides `__ * `video `__ + * The Challenges of Implementing the C Standard Library in C++ - Sivachandra Reddy * `slides `__ @@ -24,10 +65,12 @@ Talks * `slides `__ * `video `__ + * Using modern CPU instructions to improve LLVM's libc math library - Tue Ly * `slides `__ * `video `__ + * Approximating at Scale: How strto float in LLVM’s libc is faster - Michael Jones * `slides `__ diff --git a/libc/docs/threads.rst b/libc/docs/threads.rst deleted file mode 100644 index db0edacf7b468..0000000000000 --- a/libc/docs/threads.rst +++ /dev/null @@ -1,139 +0,0 @@ -.. include:: check.rst - -========= -threads.h -========= - -Macros -====== - -.. list-table:: - :widths: auto - :align: center - :header-rows: 1 - - * - Macro - - Implemented - - C23 Standard Section - - POSIX.1-2017 Standard Section - * - ONCE_FLAG_INIT - - - - 7.28.1.3 - - - * - TSS_DTOR_ITERATIONS - - - - 7.28.1.3 - - - -Functions -========= - -.. list-table:: - :widths: auto - :align: center - :header-rows: 1 - - * - Function - - Implemented - - C23 Standard Section - - POSIX.1-2017 Standard Section - * - call_once - - |check| - - 7.28.2.1 - - - * - cnd_broadcast - - |check| - - 7.28.3.1 - - - * - cnd_destroy - - |check| - - 7.28.3.2 - - - * - cnd_init - - |check| - - 7.28.3.3 - - - * - cnd_signal - - |check| - - 7.28.3.4 - - - * - cnd_timedwait - - - - 7.28.3.5 - - - * - cnd_wait - - |check| - - 7.28.3.6 - - - * - mtx_destroy - - |check| - - 7.28.4.1 - - - * - mtx_init - - |check| - - 7.28.4.2 - - - * - mtx_lock - - |check| - - 7.28.4.3 - - - * - mtx_timedlock - - - - 7.28.4.4 - - - * - mtx_trylock - - - - 7.28.4.5 - - - * - mtx_unlock - - |check| - - 7.28.4.6 - - - * - thrd_create - - |check| - - 7.28.5.1 - - - * - thrd_current - - |check| - - 7.28.5.2 - - - * - thrd_detach - - |check| - - 7.28.5.3 - - - * - thrd_equal - - |check| - - 7.28.5.4 - - - * - thrd_exit - - |check| - - 7.28.5.5 - - - * - thrd_join - - |check| - - 7.28.5.6 - - - * - thrd_sleep - - - - 7.28.5.7 - - - * - thrd_yield - - - - 7.28.5.8 - - - * - tss_create - - |check| - - 7.28.6.1 - - - * - tss_delete - - |check| - - 7.28.6.2 - - - * - tss_get - - |check| - - 7.28.6.3 - - - * - tss_set - - |check| - - 7.28.6.4 - - diff --git a/libc/fuzzing/__support/CMakeLists.txt b/libc/fuzzing/__support/CMakeLists.txt index 9d6589d78fb81..d4b324db716f6 100644 --- a/libc/fuzzing/__support/CMakeLists.txt +++ b/libc/fuzzing/__support/CMakeLists.txt @@ -24,10 +24,23 @@ add_libc_fuzzer( -D__LIBC_EXPLICIT_SIMD_OPT ) -add_libc_fuzzer( - freelist_heap_fuzz - SRCS - freelist_heap_fuzz.cpp - DEPENDS - libc.src.__support.freelist_heap -) +# TODO: FreeListHeap uses the _end symbol which conflicts with the _end symbol +# defined by GPU start.cpp files so for now we exclude this fuzzer on GPU. +if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_GPU) + add_libc_fuzzer( + freelist_heap_fuzz + SRCS + fake_heap.s + freelist_heap_fuzz.cpp + DEPENDS + libc.src.__support.freelist_heap + ) + # TODO(#119995): Remove this once sccache on Windows no longer requires + # the use of -DCMAKE_MSVC_DEBUG_INFORMATION_FORMAT=Embedded. + get_fq_target_name(freelist_heap_fuzz freelist_heap_fuzz_target_name) + set_target_properties( + ${freelist_heap_fuzz_target_name} + PROPERTIES + MSVC_DEBUG_INFORMATION_FORMAT "" + ) +endif() diff --git a/libc/fuzzing/__support/fake_heap.s b/libc/fuzzing/__support/fake_heap.s new file mode 100644 index 0000000000000..69522f53c8b1f --- /dev/null +++ b/libc/fuzzing/__support/fake_heap.s @@ -0,0 +1,15 @@ +//===-- Test fake definition for heap symbols -----------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +.globl _end, __llvm_libc_heap_limit + +.bss +_end: +.fill 1024 +__llvm_libc_heap_limit: + diff --git a/libc/fuzzing/string/CMakeLists.txt b/libc/fuzzing/string/CMakeLists.txt index 9dd4fceee3b59..efda80b59c951 100644 --- a/libc/fuzzing/string/CMakeLists.txt +++ b/libc/fuzzing/string/CMakeLists.txt @@ -38,5 +38,5 @@ add_libc_fuzzer( SRCS bcmp_fuzz.cpp DEPENDS - libc.src.string.bcmp + libc.src.strings.bcmp ) diff --git a/libc/fuzzing/string/bcmp_fuzz.cpp b/libc/fuzzing/string/bcmp_fuzz.cpp index 65949dfdf0c56..710d115b0ae80 100644 --- a/libc/fuzzing/string/bcmp_fuzz.cpp +++ b/libc/fuzzing/string/bcmp_fuzz.cpp @@ -9,7 +9,7 @@ /// Fuzzing test for llvm-libc bcmp implementation. /// //===----------------------------------------------------------------------===// -#include "src/string/bcmp.h" +#include "src/strings/bcmp.h" #include #include #include diff --git a/libc/hdr/CMakeLists.txt b/libc/hdr/CMakeLists.txt index 93da271f5e040..5eb311f4bb229 100644 --- a/libc/hdr/CMakeLists.txt +++ b/libc/hdr/CMakeLists.txt @@ -135,10 +135,18 @@ add_proxy_header_library( libc.include.llvm-libc-macros.unistd_macros ) +if (WIN32) + set(windows_addtional_time_macros libc.include.llvm-libc-macros.windows.time_macros_ext) +else() + set(windows_addtional_time_macros "") +endif() + add_proxy_header_library( time_macros HDRS time_macros.h + DEPENDS + ${windows_addtional_time_macros} FULL_BUILD_DEPENDS libc.include.time libc.include.llvm-libc-macros.time_macros diff --git a/libc/hdr/fcntl_overlay.h b/libc/hdr/fcntl_overlay.h index c1cc98b0ebb2c..17ae78b3d0eca 100644 --- a/libc/hdr/fcntl_overlay.h +++ b/libc/hdr/fcntl_overlay.h @@ -20,6 +20,11 @@ // `__USE_FORTIFY_LEVEL`, which will be temporarily disabled // with `_FORTIFY_SOURCE`. +#ifdef _FORTIFY_SOURCE +#define LIBC_OLD_FORTIFY_SOURCE _FORTIFY_SOURCE +#undef _FORTIFY_SOURCE +#endif + #ifdef __USE_FORTIFY_LEVEL #define LIBC_OLD_USE_FORTIFY_LEVEL __USE_FORTIFY_LEVEL #undef __USE_FORTIFY_LEVEL @@ -28,6 +33,11 @@ #include +#ifdef LIBC_OLD_FORTIFY_SOURCE +#define _FORTIFY_SOURCE LIBC_OLD_FORTIFY_SOURCE +#undef LIBC_OLD_FORTIFY_SOURCE +#endif + #ifdef LIBC_OLD_USE_FORTIFY_LEVEL #undef __USE_FORTIFY_LEVEL #define __USE_FORTIFY_LEVEL LIBC_OLD_USE_FORTIFY_LEVEL diff --git a/libc/hdr/func/free.h b/libc/hdr/func/free.h index b1190a777da32..316556b21e3b0 100644 --- a/libc/hdr/func/free.h +++ b/libc/hdr/func/free.h @@ -10,7 +10,8 @@ #define LLVM_LIBC_HDR_FUNC_FREE_H #ifdef LIBC_FULL_BUILD -extern "C" void free(void *); + +extern "C" void free(void *) noexcept; #else // Overlay mode diff --git a/libc/hdr/func/malloc.h b/libc/hdr/func/malloc.h index b395f41f2bce2..8281021f79969 100644 --- a/libc/hdr/func/malloc.h +++ b/libc/hdr/func/malloc.h @@ -10,8 +10,10 @@ #define LLVM_LIBC_HDR_FUNC_MALLOC_H #ifdef LIBC_FULL_BUILD + #include "hdr/types/size_t.h" -extern "C" void *malloc(size_t); + +extern "C" void *malloc(size_t) noexcept; #else // Overlay mode diff --git a/libc/hdr/func/realloc.h b/libc/hdr/func/realloc.h index 0096045e8330b..ecb29541fe34a 100644 --- a/libc/hdr/func/realloc.h +++ b/libc/hdr/func/realloc.h @@ -10,8 +10,10 @@ #define LLVM_LIBC_HDR_FUNC_REALLOC_H #ifdef LIBC_FULL_BUILD + #include "hdr/types/size_t.h" -extern "C" void *realloc(void *ptr, size_t new_size); + +extern "C" void *realloc(void *ptr, size_t new_size) noexcept; #else // Overlay mode diff --git a/libc/hdr/time_macros.h b/libc/hdr/time_macros.h index dc36fe66f7a80..4488a24848c35 100644 --- a/libc/hdr/time_macros.h +++ b/libc/hdr/time_macros.h @@ -19,4 +19,10 @@ #endif // LLVM_LIBC_FULL_BUILD +// TODO: For now, on windows, let's always include the extension header. +// We will need to decide how to export this header. +#ifdef _WIN32 +#include "include/llvm-libc-macros/windows/time-macros-ext.h" +#endif // _WIN32 + #endif // LLVM_LIBC_HDR_TIME_MACROS_H diff --git a/libc/hdr/types/CMakeLists.txt b/libc/hdr/types/CMakeLists.txt index c4d14e6f89313..ce3ecefe36438 100644 --- a/libc/hdr/types/CMakeLists.txt +++ b/libc/hdr/types/CMakeLists.txt @@ -51,6 +51,8 @@ add_proxy_header_library( struct_flock HDRS struct_flock.h + DEPENDS + libc.hdr.fcntl_overlay FULL_BUILD_DEPENDS libc.include.llvm-libc-types.struct_flock ) @@ -59,6 +61,8 @@ add_proxy_header_library( struct_flock64 HDRS struct_flock64.h + DEPENDS + libc.hdr.fcntl_overlay FULL_BUILD_DEPENDS libc.include.llvm-libc-types.struct_flock64 ) @@ -67,6 +71,8 @@ add_proxy_header_library( struct_f_owner_ex HDRS struct_f_owner_ex.h + DEPENDS + libc.hdr.fcntl_overlay FULL_BUILD_DEPENDS libc.include.llvm-libc-types.struct_f_owner_ex ) @@ -131,7 +137,6 @@ add_proxy_header_library( clockid_t.h FULL_BUILD_DEPENDS libc.include.llvm-libc-types.clockid_t - libc.include.sys_types ) add_proxy_header_library( @@ -167,7 +172,6 @@ add_proxy_header_library( pid_t.h FULL_BUILD_DEPENDS libc.include.llvm-libc-types.pid_t - libc.include.sys_types ) add_proxy_header_library( diff --git a/libc/hdr/types/clockid_t.h b/libc/hdr/types/clockid_t.h index 333342072a2ff..729e580aba438 100644 --- a/libc/hdr/types/clockid_t.h +++ b/libc/hdr/types/clockid_t.h @@ -9,7 +9,8 @@ #ifndef LLVM_LIBC_HDR_TYPES_CLOCKID_T_H #define LLVM_LIBC_HDR_TYPES_CLOCKID_T_H -#ifdef LIBC_FULL_BUILD +// TODO: we will need to decide how to export extension to windows. +#if defined(LIBC_FULL_BUILD) || defined(_WIN32) #include "include/llvm-libc-types/clockid_t.h" diff --git a/libc/hdr/types/struct_f_owner_ex.h b/libc/hdr/types/struct_f_owner_ex.h index 49985115ae4bb..6e37cea6df84d 100644 --- a/libc/hdr/types/struct_f_owner_ex.h +++ b/libc/hdr/types/struct_f_owner_ex.h @@ -14,7 +14,7 @@ #else -#include +#include "hdr/fcntl_overlay.h" #endif // LIBC_FULL_BUILD diff --git a/libc/hdr/types/struct_flock.h b/libc/hdr/types/struct_flock.h index a552b91c432b3..6a6c928e6fa6d 100644 --- a/libc/hdr/types/struct_flock.h +++ b/libc/hdr/types/struct_flock.h @@ -14,7 +14,7 @@ #else -#include +#include "hdr/fcntl_overlay.h" #endif // LIBC_FULL_BUILD diff --git a/libc/hdr/types/struct_flock64.h b/libc/hdr/types/struct_flock64.h index 84fe67816c337..fcfda59479a29 100644 --- a/libc/hdr/types/struct_flock64.h +++ b/libc/hdr/types/struct_flock64.h @@ -14,7 +14,7 @@ #else -#include +#include "hdr/fcntl_overlay.h" #endif // LIBC_FULL_BUILD diff --git a/libc/hdrgen/yaml/complex.yaml b/libc/hdrgen/yaml/complex.yaml new file mode 100644 index 0000000000000..be0d3c9ae59b4 --- /dev/null +++ b/libc/hdrgen/yaml/complex.yaml @@ -0,0 +1,105 @@ +header: complex.h +macros: [] +types: + - type_name: cfloat16 + - type_name: cfloat128 + - type_name: float128 +enums: [] +objects: [] +functions: + - name: cimag + standards: + - stdc + return_type: double + arguments: + - type: _Complex double + - name: cimagf + standards: + - stdc + return_type: float + arguments: + - type: _Complex float + - name: cimagl + standards: + - stdc + return_type: long double + arguments: + - type: _Complex long double + - name: cimagf16 + standards: + - stdc + return_type: _Float16 + arguments: + - type: cfloat16 + guard: LIBC_TYPES_HAS_CFLOAT16 + - name: cimagf128 + standards: + - stdc + return_type: float128 + arguments: + - type: cfloat128 + guard: LIBC_TYPES_HAS_CFLOAT128 + - name: creal + standards: + - stdc + return_type: double + arguments: + - type: _Complex double + - name: crealf + standards: + - stdc + return_type: float + arguments: + - type: _Complex float + - name: creall + standards: + - stdc + return_type: long double + arguments: + - type: _Complex long double + - name: crealf16 + standards: + - stdc + return_type: _Float16 + arguments: + - type: cfloat16 + guard: LIBC_TYPES_HAS_CFLOAT16 + - name: crealf128 + standards: + - stdc + return_type: float128 + arguments: + - type: cfloat128 + guard: LIBC_TYPES_HAS_CFLOAT128 + - name: conj + standards: + - stdc + return_type: _Complex double + arguments: + - type: _Complex double + - name: conjf + standards: + - stdc + return_type: _Complex float + arguments: + - type: _Complex float + - name: conjl + standards: + - stdc + return_type: _Complex long double + arguments: + - type: _Complex long double + - name: conjf16 + standards: + - stdc + return_type: cfloat16 + arguments: + - type: cfloat16 + guard: LIBC_TYPES_HAS_CFLOAT16 + - name: conjf128 + standards: + - stdc + return_type: cfloat128 + arguments: + - type: cfloat128 + guard: LIBC_TYPES_HAS_CFLOAT128 diff --git a/libc/hdrgen/yaml/math.yaml b/libc/hdrgen/yaml/math.yaml index 00efc34789667..3b8caec66bbfd 100644 --- a/libc/hdrgen/yaml/math.yaml +++ b/libc/hdrgen/yaml/math.yaml @@ -200,6 +200,13 @@ functions: return_type: float arguments: - type: float + - name: cosf16 + standards: + - stdc + return_type: _Float16 + arguments: + - type: _Float16 + guard: LIBC_TYPES_HAS_FLOAT16 - name: coshf standards: - stdc diff --git a/libc/hdrgen/yaml/sys/mman.yaml b/libc/hdrgen/yaml/sys/mman.yaml index dd53eb60d1ec5..962ca3591917f 100644 --- a/libc/hdrgen/yaml/sys/mman.yaml +++ b/libc/hdrgen/yaml/sys/mman.yaml @@ -132,10 +132,3 @@ functions: return_type: int arguments: - type: const char * - - name: process_mrelease - standards: - - Linux - return_type: int - arguments: - - type: int - - type: unsigned int diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt index 6fdaa6c03c0c8..18ce8e22d1a0a 100644 --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -389,7 +389,7 @@ add_header_macro( pthread.h.def pthread.h DEPENDS - .llvm_libc_common_h + .llvm-libc-macros.pthread_macros .llvm-libc-types.__atfork_callback_t .llvm-libc-types.__pthread_once_func_t .llvm-libc-types.__pthread_start_t @@ -404,6 +404,7 @@ add_header_macro( .llvm-libc-types.pthread_rwlockattr_t .llvm-libc-types.pthread_spinlock_t .llvm-libc-types.pthread_t + .llvm_libc_common_h ) add_header_macro( diff --git a/libc/include/llvm-libc-macros/CMakeLists.txt b/libc/include/llvm-libc-macros/CMakeLists.txt index 75194923a452f..9d5d9f6544288 100644 --- a/libc/include/llvm-libc-macros/CMakeLists.txt +++ b/libc/include/llvm-libc-macros/CMakeLists.txt @@ -315,3 +315,9 @@ add_macro_header( HDR locale-macros.h ) + +add_macro_header( + pthread_macros + HDR + pthread-macros.h +) diff --git a/libc/include/llvm-libc-macros/pthread-macros.h b/libc/include/llvm-libc-macros/pthread-macros.h new file mode 100644 index 0000000000000..8a144dbd2e611 --- /dev/null +++ b/libc/include/llvm-libc-macros/pthread-macros.h @@ -0,0 +1,37 @@ +//===-- Definition of pthread macros --------------------------------------===// +// +// 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_MACROS_PTHREAD_MACRO_H +#define LLVM_LIBC_MACROS_PTHREAD_MACRO_H + +#define PTHREAD_CREATE_JOINABLE 0 +#define PTHREAD_CREATE_DETACHED 1 + +#define PTHREAD_MUTEX_NORMAL 0 +#define PTHREAD_MUTEX_ERRORCHECK 1 +#define PTHREAD_MUTEX_RECURSIVE 2 +#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL + +#define PTHREAD_MUTEX_STALLED 0 +#define PTHREAD_MUTEX_ROBUST 1 + +#define PTHREAD_ONCE_INIT {0} + +#define PTHREAD_PROCESS_PRIVATE 0 +#define PTHREAD_PROCESS_SHARED 1 + +#define PTHREAD_MUTEX_INITIALIZER {0} +#define PTHREAD_RWLOCK_INITIALIZER {0} + +// glibc extensions +#define PTHREAD_STACK_MIN (1 << 14) // 16KB +#define PTHREAD_RWLOCK_PREFER_READER_NP 0 +#define PTHREAD_RWLOCK_PREFER_WRITER_NP 1 +#define PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 2 + +#endif // LLVM_LIBC_MACROS_PTHREAD_MACRO_H diff --git a/libc/include/llvm-libc-macros/windows/CMakeLists.txt b/libc/include/llvm-libc-macros/windows/CMakeLists.txt new file mode 100644 index 0000000000000..48afc795178a0 --- /dev/null +++ b/libc/include/llvm-libc-macros/windows/CMakeLists.txt @@ -0,0 +1,6 @@ +add_header( + time_macros_ext + HDR + time-macros-ext.h +) + diff --git a/libc/include/llvm-libc-macros/windows/time-macros-ext.h b/libc/include/llvm-libc-macros/windows/time-macros-ext.h new file mode 100644 index 0000000000000..71d914b451877 --- /dev/null +++ b/libc/include/llvm-libc-macros/windows/time-macros-ext.h @@ -0,0 +1,17 @@ +//===-- Windows Time Macros Extension -------------------------------------===// +// +// 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_MACROS_WINDOWS_TIME_MACROS_EXT_H +#define LLVM_LIBC_MACROS_WINDOWS_TIME_MACROS_EXT_H + +#define CLOCK_MONOTONIC 0 +#define CLOCK_REALTIME 1 +#define CLOCK_PROCESS_CPUTIME_ID 2 +#define CLOCK_THREAD_CPUTIME_ID 3 + +#endif // LLVM_LIBC_MACROS_WINDOWS_TIME_MACROS_EXT_H diff --git a/libc/include/llvm-libc-types/cfloat128.h b/libc/include/llvm-libc-types/cfloat128.h index a371671cf6235..f76a0c1c2f5af 100644 --- a/libc/include/llvm-libc-types/cfloat128.h +++ b/libc/include/llvm-libc-types/cfloat128.h @@ -35,6 +35,7 @@ typedef _Complex _Float128 cfloat128; typedef _Complex __float128 cfloat128; #elif (LDBL_MANT_DIG == 113) #define LIBC_TYPES_HAS_CFLOAT128 +#define LIBC_TYPES_CFLOAT128_IS_COMPLEX_LONG_DOUBLE typedef _Complex long double cfloat128; #endif diff --git a/libc/include/pthread.h.def b/libc/include/pthread.h.def index 4dbeed6b5f321..aa1e9983e4bb9 100644 --- a/libc/include/pthread.h.def +++ b/libc/include/pthread.h.def @@ -10,39 +10,7 @@ #define LLVM_LIBC_PTHREAD_H #include "__llvm-libc-common.h" - -// TODO: move to a pthreads-macros.h file: -// https://github.com/llvm/llvm-project/issues/88997 - -#define PTHREAD_STACK_MIN (1 << 14) // 16KB - -#define PTHREAD_MUTEX_INITIALIZER {0} -#define PTHREAD_RWLOCK_INITIALIZER {} -#define PTHREAD_ONCE_INIT {0} - -enum { - PTHREAD_CREATE_JOINABLE = 0x0, - PTHREAD_CREATE_DETACHED = 0x1, - - PTHREAD_MUTEX_NORMAL = 0x0, - PTHREAD_MUTEX_ERRORCHECK = 0x1, - PTHREAD_MUTEX_RECURSIVE = 0x2, - PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL, - - PTHREAD_PROCESS_PRIVATE = 0x0, - PTHREAD_PROCESS_SHARED = 0x1, - - PTHREAD_MUTEX_STALLED = 0x0, - PTHREAD_MUTEX_ROBUST = 0x1, -}; - -#define PTHREAD_PROCESS_PRIVATE 0 -#define PTHREAD_PROCESS_SHARED 1 - -#define PTHREAD_RWLOCK_PREFER_READER_NP 0 -#define PTHREAD_RWLOCK_PREFER_WRITER_NP 1 -#define PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 2 - +#include "llvm-libc-macros/pthread-macros.h" %%public_api() diff --git a/libc/include/sys/syscall.h.def b/libc/include/sys/syscall.h.def index 11758ea8336dd..03c19eb0885ed 100644 --- a/libc/include/sys/syscall.h.def +++ b/libc/include/sys/syscall.h.def @@ -2349,12 +2349,5 @@ #define SYS_writev __NR_writev #endif -#ifdef __NR_process_mrelease -#define SYS_process_mrelease __NR_process_mrelease -#endif - -#ifdef __NR_pidfd_open -#define SYS_pidfd_open __NR_pidfd_open -#endif #endif // LLVM_LIBC_SYS_SYSCALL_H diff --git a/libc/shared/rpc.h b/libc/shared/rpc.h index 3f586744377d9..dd46d5dcb3dc0 100644 --- a/libc/shared/rpc.h +++ b/libc/shared/rpc.h @@ -20,12 +20,6 @@ #include "rpc_util.h" -#include - -#ifndef RPC_INLINE -#define RPC_INLINE inline -#endif - namespace rpc { /// Use scoped atomic variants if they are available for the target. @@ -44,9 +38,9 @@ namespace rpc { /// Generic codes that can be used whem implementing the server. enum Status { - SUCCESS = 0x0, - ERROR = 0x1000, - UNHANDLED_OPCODE = 0x1001, + RPC_SUCCESS = 0x0, + RPC_ERROR = 0x1000, + RPC_UNHANDLED_OPCODE = 0x1001, }; /// A fixed size channel used to communicate between the RPC client and server. @@ -78,12 +72,12 @@ constexpr static uint64_t MAX_PORT_COUNT = 4096; /// - The server will always start with a 'recv' operation. /// - Every 'send' or 'recv' call is mirrored by the other process. template struct Process { - RPC_INLINE Process() = default; - RPC_INLINE Process(const Process &) = delete; - RPC_INLINE Process &operator=(const Process &) = delete; - RPC_INLINE Process(Process &&) = default; - RPC_INLINE Process &operator=(Process &&) = default; - RPC_INLINE ~Process() = default; + RPC_ATTRS Process() = default; + RPC_ATTRS Process(const Process &) = delete; + RPC_ATTRS Process &operator=(const Process &) = delete; + RPC_ATTRS Process(Process &&) = default; + RPC_ATTRS Process &operator=(Process &&) = default; + RPC_ATTRS ~Process() = default; const uint32_t port_count = 0; const uint32_t *const inbox = nullptr; @@ -94,7 +88,7 @@ template struct Process { static constexpr uint64_t NUM_BITS_IN_WORD = sizeof(uint32_t) * 8; uint32_t lock[MAX_PORT_COUNT / NUM_BITS_IN_WORD] = {0}; - RPC_INLINE Process(uint32_t port_count, void *buffer) + RPC_ATTRS Process(uint32_t port_count, void *buffer) : port_count(port_count), inbox(reinterpret_cast( advance(buffer, inbox_offset(port_count)))), outbox(reinterpret_cast( @@ -113,20 +107,20 @@ template struct Process { /// Header header[port_count]; /// Buffer packet[port_count][lane_size]; /// }; - RPC_INLINE static constexpr uint64_t allocation_size(uint32_t port_count, - uint32_t lane_size) { + RPC_ATTRS static constexpr uint64_t allocation_size(uint32_t port_count, + uint32_t lane_size) { return buffer_offset(port_count) + buffer_bytes(port_count, lane_size); } /// Retrieve the inbox state from memory shared between processes. - RPC_INLINE uint32_t load_inbox(uint64_t lane_mask, uint32_t index) const { + RPC_ATTRS uint32_t load_inbox(uint64_t lane_mask, uint32_t index) const { return rpc::broadcast_value( lane_mask, __scoped_atomic_load_n(&inbox[index], __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM)); } /// Retrieve the outbox state from memory shared between processes. - RPC_INLINE uint32_t load_outbox(uint64_t lane_mask, uint32_t index) const { + RPC_ATTRS uint32_t load_outbox(uint64_t lane_mask, uint32_t index) const { return rpc::broadcast_value( lane_mask, __scoped_atomic_load_n(&outbox[index], __ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM)); @@ -136,7 +130,7 @@ template struct Process { /// Equivalent to loading outbox followed by store of the inverted value /// The outbox is write only by this warp and tracking the value locally is /// cheaper than calling load_outbox to get the value to store. - RPC_INLINE uint32_t invert_outbox(uint32_t index, uint32_t current_outbox) { + RPC_ATTRS uint32_t invert_outbox(uint32_t index, uint32_t current_outbox) { uint32_t inverted_outbox = !current_outbox; __scoped_atomic_thread_fence(__ATOMIC_RELEASE, __MEMORY_SCOPE_SYSTEM); __scoped_atomic_store_n(&outbox[index], inverted_outbox, __ATOMIC_RELAXED, @@ -146,8 +140,8 @@ template struct Process { // Given the current outbox and inbox values, wait until the inbox changes // to indicate that this thread owns the buffer element. - RPC_INLINE void wait_for_ownership(uint64_t lane_mask, uint32_t index, - uint32_t outbox, uint32_t in) { + RPC_ATTRS void wait_for_ownership(uint64_t lane_mask, uint32_t index, + uint32_t outbox, uint32_t in) { while (buffer_unavailable(in, outbox)) { sleep_briefly(); in = load_inbox(lane_mask, index); @@ -158,14 +152,14 @@ template struct Process { /// The packet is a linearly allocated array of buffers used to communicate /// with the other process. This function returns the appropriate slot in this /// array such that the process can operate on an entire warp or wavefront. - RPC_INLINE Buffer *get_packet(uint32_t index, uint32_t lane_size) { + RPC_ATTRS Buffer *get_packet(uint32_t index, uint32_t lane_size) { return &packet[index * lane_size]; } /// Determines if this process needs to wait for ownership of the buffer. We /// invert the condition on one of the processes to indicate that if one /// process owns the buffer then the other does not. - RPC_INLINE static bool buffer_unavailable(uint32_t in, uint32_t out) { + RPC_ATTRS static bool buffer_unavailable(uint32_t in, uint32_t out) { bool cond = in != out; return Invert ? !cond : cond; } @@ -174,7 +168,7 @@ template struct Process { /// lane_mask is a bitmap of the threads in the warp that would hold the /// single lock on success, e.g. the result of rpc::get_lane_mask() /// The lock is held when the n-th bit of the lock bitfield is set. - RPC_INLINE bool try_lock(uint64_t lane_mask, uint32_t index) { + RPC_ATTRS bool try_lock(uint64_t lane_mask, uint32_t index) { // On amdgpu, test and set to the nth lock bit and a sync_lane would suffice // On volta, need to handle differences between the threads running and // the threads that were detected in the previous call to get_lane_mask() @@ -214,7 +208,7 @@ template struct Process { /// Unlock the lock at index. We need a lane sync to keep this function /// convergent, otherwise the compiler will sink the store and deadlock. - RPC_INLINE void unlock(uint64_t lane_mask, uint32_t index) { + RPC_ATTRS void unlock(uint64_t lane_mask, uint32_t index) { // Do not move any writes past the unlock. __scoped_atomic_thread_fence(__ATOMIC_RELEASE, __MEMORY_SCOPE_DEVICE); @@ -227,40 +221,40 @@ template struct Process { } /// Number of bytes to allocate for an inbox or outbox. - RPC_INLINE static constexpr uint64_t mailbox_bytes(uint32_t port_count) { + RPC_ATTRS static constexpr uint64_t mailbox_bytes(uint32_t port_count) { return port_count * sizeof(uint32_t); } /// Number of bytes to allocate for the buffer containing the packets. - RPC_INLINE static constexpr uint64_t buffer_bytes(uint32_t port_count, - uint32_t lane_size) { + RPC_ATTRS static constexpr uint64_t buffer_bytes(uint32_t port_count, + uint32_t lane_size) { return port_count * lane_size * sizeof(Buffer); } /// Offset of the inbox in memory. This is the same as the outbox if inverted. - RPC_INLINE static constexpr uint64_t inbox_offset(uint32_t port_count) { + RPC_ATTRS static constexpr uint64_t inbox_offset(uint32_t port_count) { return Invert ? mailbox_bytes(port_count) : 0; } /// Offset of the outbox in memory. This is the same as the inbox if inverted. - RPC_INLINE static constexpr uint64_t outbox_offset(uint32_t port_count) { + RPC_ATTRS static constexpr uint64_t outbox_offset(uint32_t port_count) { return Invert ? 0 : mailbox_bytes(port_count); } /// Offset of the buffer containing the packets after the inbox and outbox. - RPC_INLINE static constexpr uint64_t header_offset(uint32_t port_count) { + RPC_ATTRS static constexpr uint64_t header_offset(uint32_t port_count) { return align_up(2 * mailbox_bytes(port_count), alignof(Header)); } /// Offset of the buffer containing the packets after the inbox and outbox. - RPC_INLINE static constexpr uint64_t buffer_offset(uint32_t port_count) { + RPC_ATTRS static constexpr uint64_t buffer_offset(uint32_t port_count) { return align_up(header_offset(port_count) + port_count * sizeof(Header), alignof(Buffer)); } /// Conditionally set the n-th bit in the atomic bitfield. - RPC_INLINE static constexpr uint32_t set_nth(uint32_t *bits, uint32_t index, - bool cond) { + RPC_ATTRS static constexpr uint32_t set_nth(uint32_t *bits, uint32_t index, + bool cond) { uint32_t slot = index / NUM_BITS_IN_WORD; uint32_t bit = index % NUM_BITS_IN_WORD; return __scoped_atomic_fetch_or(&bits[slot], @@ -270,8 +264,8 @@ template struct Process { } /// Conditionally clear the n-th bit in the atomic bitfield. - RPC_INLINE static constexpr uint32_t clear_nth(uint32_t *bits, uint32_t index, - bool cond) { + RPC_ATTRS static constexpr uint32_t clear_nth(uint32_t *bits, uint32_t index, + bool cond) { uint32_t slot = index / NUM_BITS_IN_WORD; uint32_t bit = index % NUM_BITS_IN_WORD; return __scoped_atomic_fetch_and(&bits[slot], @@ -283,8 +277,8 @@ template struct Process { /// Invokes a function accross every active buffer across the total lane size. template -RPC_INLINE static void invoke_rpc(F &&fn, uint32_t lane_size, - uint64_t lane_mask, Buffer *slot) { +RPC_ATTRS static void invoke_rpc(F &&fn, uint32_t lane_size, uint64_t lane_mask, + Buffer *slot) { if constexpr (is_process_gpu()) { fn(&slot[rpc::get_lane_id()], rpc::get_lane_id()); } else { @@ -298,40 +292,37 @@ RPC_INLINE static void invoke_rpc(F &&fn, uint32_t lane_size, /// processes. A port is conceptually an index into the memory provided by the /// underlying process that is guarded by a lock bit. template struct Port { - RPC_INLINE Port(Process &process, uint64_t lane_mask, uint32_t lane_size, - uint32_t index, uint32_t out) + RPC_ATTRS Port(Process &process, uint64_t lane_mask, uint32_t lane_size, + uint32_t index, uint32_t out) : process(process), lane_mask(lane_mask), lane_size(lane_size), index(index), out(out), receive(false), owns_buffer(true) {} - RPC_INLINE ~Port() = default; + RPC_ATTRS ~Port() = default; private: - RPC_INLINE Port(const Port &) = delete; - RPC_INLINE Port &operator=(const Port &) = delete; - RPC_INLINE Port(Port &&) = default; - RPC_INLINE Port &operator=(Port &&) = default; + RPC_ATTRS Port(const Port &) = delete; + RPC_ATTRS Port &operator=(const Port &) = delete; + RPC_ATTRS Port(Port &&) = default; + RPC_ATTRS Port &operator=(Port &&) = default; friend struct Client; friend struct Server; friend class rpc::optional>; public: - template RPC_INLINE void recv(U use); - template RPC_INLINE void send(F fill); - template - RPC_INLINE void send_and_recv(F fill, U use); - template RPC_INLINE void recv_and_send(W work); - RPC_INLINE void send_n(const void *const *src, uint64_t *size); - RPC_INLINE void send_n(const void *src, uint64_t size); + template RPC_ATTRS void recv(U use); + template RPC_ATTRS void send(F fill); + template RPC_ATTRS void send_and_recv(F fill, U use); + template RPC_ATTRS void recv_and_send(W work); + RPC_ATTRS void send_n(const void *const *src, uint64_t *size); + RPC_ATTRS void send_n(const void *src, uint64_t size); template - RPC_INLINE void recv_n(void **dst, uint64_t *size, A &&alloc); + RPC_ATTRS void recv_n(void **dst, uint64_t *size, A &&alloc); - RPC_INLINE uint32_t get_opcode() const { - return process.header[index].opcode; - } + RPC_ATTRS uint32_t get_opcode() const { return process.header[index].opcode; } - RPC_INLINE uint32_t get_index() const { return index; } + RPC_ATTRS uint32_t get_index() const { return index; } - RPC_INLINE void close() { + RPC_ATTRS void close() { // Wait for all lanes to finish using the port. rpc::sync_lane(lane_mask); @@ -354,16 +345,16 @@ template struct Port { /// The RPC client used to make requests to the server. struct Client { - RPC_INLINE Client() = default; - RPC_INLINE Client(const Client &) = delete; - RPC_INLINE Client &operator=(const Client &) = delete; - RPC_INLINE ~Client() = default; + RPC_ATTRS Client() = default; + RPC_ATTRS Client(const Client &) = delete; + RPC_ATTRS Client &operator=(const Client &) = delete; + RPC_ATTRS ~Client() = default; - RPC_INLINE Client(uint32_t port_count, void *buffer) + RPC_ATTRS Client(uint32_t port_count, void *buffer) : process(port_count, buffer) {} using Port = rpc::Port; - template RPC_INLINE Port open(); + template RPC_ATTRS Port open(); private: Process process; @@ -371,21 +362,21 @@ struct Client { /// The RPC server used to respond to the client. struct Server { - RPC_INLINE Server() = default; - RPC_INLINE Server(const Server &) = delete; - RPC_INLINE Server &operator=(const Server &) = delete; - RPC_INLINE ~Server() = default; + RPC_ATTRS Server() = default; + RPC_ATTRS Server(const Server &) = delete; + RPC_ATTRS Server &operator=(const Server &) = delete; + RPC_ATTRS ~Server() = default; - RPC_INLINE Server(uint32_t port_count, void *buffer) + RPC_ATTRS Server(uint32_t port_count, void *buffer) : process(port_count, buffer) {} using Port = rpc::Port; - RPC_INLINE rpc::optional try_open(uint32_t lane_size, - uint32_t start = 0); - RPC_INLINE Port open(uint32_t lane_size); + RPC_ATTRS rpc::optional try_open(uint32_t lane_size, + uint32_t start = 0); + RPC_ATTRS Port open(uint32_t lane_size); - RPC_INLINE static uint64_t allocation_size(uint32_t lane_size, - uint32_t port_count) { + RPC_ATTRS static uint64_t allocation_size(uint32_t lane_size, + uint32_t port_count) { return Process::allocation_size(port_count, lane_size); } @@ -394,7 +385,7 @@ struct Server { }; /// Applies \p fill to the shared buffer and initiates a send operation. -template template RPC_INLINE void Port::send(F fill) { +template template RPC_ATTRS void Port::send(F fill) { uint32_t in = owns_buffer ? out ^ T : process.load_inbox(lane_mask, index); // We need to wait until we own the buffer before sending. @@ -409,7 +400,7 @@ template template RPC_INLINE void Port::send(F fill) { } /// Applies \p use to the shared buffer and acknowledges the send. -template template RPC_INLINE void Port::recv(U use) { +template template RPC_ATTRS void Port::recv(U use) { // We only exchange ownership of the buffer during a receive if we are waiting // for a previous receive to finish. if (receive) { @@ -432,7 +423,7 @@ template template RPC_INLINE void Port::recv(U use) { /// Combines a send and receive into a single function. template template -RPC_INLINE void Port::send_and_recv(F fill, U use) { +RPC_ATTRS void Port::send_and_recv(F fill, U use) { send(fill); recv(use); } @@ -442,7 +433,7 @@ RPC_INLINE void Port::send_and_recv(F fill, U use) { /// the copy back. template template -RPC_INLINE void Port::recv_and_send(W work) { +RPC_ATTRS void Port::recv_and_send(W work) { recv(work); send([](Buffer *, uint32_t) { /* no-op */ }); } @@ -450,7 +441,7 @@ RPC_INLINE void Port::recv_and_send(W work) { /// Helper routine to simplify the interface when sending from the GPU using /// thread private pointers to the underlying value. template -RPC_INLINE void Port::send_n(const void *src, uint64_t size) { +RPC_ATTRS void Port::send_n(const void *src, uint64_t size) { const void **src_ptr = &src; uint64_t *size_ptr = &size; send_n(src_ptr, size_ptr); @@ -459,7 +450,7 @@ RPC_INLINE void Port::send_n(const void *src, uint64_t size) { /// Sends an arbitrarily sized data buffer \p src across the shared channel in /// multiples of the packet length. template -RPC_INLINE void Port::send_n(const void *const *src, uint64_t *size) { +RPC_ATTRS void Port::send_n(const void *const *src, uint64_t *size) { uint64_t num_sends = 0; send([&](Buffer *buffer, uint32_t id) { reinterpret_cast(buffer->data)[0] = lane_value(size, id); @@ -490,7 +481,7 @@ RPC_INLINE void Port::send_n(const void *const *src, uint64_t *size) { /// size of the data so that we can initialize the size of the \p dst buffer. template template -RPC_INLINE void Port::recv_n(void **dst, uint64_t *size, A &&alloc) { +RPC_ATTRS void Port::recv_n(void **dst, uint64_t *size, A &&alloc) { uint64_t num_recvs = 0; recv([&](Buffer *buffer, uint32_t id) { lane_value(size, id) = reinterpret_cast(buffer->data)[0]; @@ -524,7 +515,7 @@ RPC_INLINE void Port::recv_n(void **dst, uint64_t *size, A &&alloc) { /// port. Each port instance uses an associated \p opcode to tell the server /// what to do. The Client interface provides the appropriate lane size to the /// port using the platform's returned value. -template RPC_INLINE Client::Port Client::open() { +template RPC_ATTRS Client::Port Client::open() { // Repeatedly perform a naive linear scan for a port that can be opened to // send data. for (uint32_t index = 0;; ++index) { @@ -558,7 +549,7 @@ template RPC_INLINE Client::Port Client::open() { /// Attempts to open a port to use as the server. The server can only open a /// port if it has a pending receive operation -RPC_INLINE rpc::optional +RPC_ATTRS rpc::optional Server::try_open(uint32_t lane_size, uint32_t start) { // Perform a naive linear scan for a port that has a pending request. for (uint32_t index = start; index < process.port_count; ++index) { @@ -588,7 +579,7 @@ Server::try_open(uint32_t lane_size, uint32_t start) { return rpc::nullopt; } -RPC_INLINE Server::Port Server::open(uint32_t lane_size) { +RPC_ATTRS Server::Port Server::open(uint32_t lane_size) { for (;;) { if (rpc::optional p = try_open(lane_size)) return rpc::move(p.value()); @@ -596,6 +587,7 @@ RPC_INLINE Server::Port Server::open(uint32_t lane_size) { } } +#undef RPC_ATTRS #if !__has_builtin(__scoped_atomic_load_n) #undef __scoped_atomic_load_n #undef __scoped_atomic_store_n diff --git a/libc/shared/rpc_util.h b/libc/shared/rpc_util.h index bb0177c01b85e..9406de59f63b7 100644 --- a/libc/shared/rpc_util.h +++ b/libc/shared/rpc_util.h @@ -12,7 +12,9 @@ #include #include -#if defined(__NVPTX__) || defined(__AMDGPU__) +#if (defined(__NVPTX__) || defined(__AMDGPU__)) && \ + !((defined(__CUDA__) && !defined(__CUDA_ARCH__)) || \ + (defined(__HIP__) && !defined(__HIP_DEVICE_COMPILE__))) #include #define RPC_TARGET_IS_GPU #endif @@ -22,8 +24,12 @@ #define __has_builtin(x) 0 #endif -#ifndef RPC_INLINE -#define RPC_INLINE inline +#ifndef RPC_ATTRS +#if defined(__CUDA__) || defined(__HIP__) +#define RPC_ATTRS __attribute__((host, device)) inline +#else +#define RPC_ATTRS inline +#endif #endif namespace rpc { @@ -45,26 +51,26 @@ template struct is_const : type_constant {}; /// Freestanding implementation of std::move. template -RPC_INLINE constexpr typename remove_reference::type &&move(T &&t) { +RPC_ATTRS constexpr typename remove_reference::type &&move(T &&t) { return static_cast::type &&>(t); } /// Freestanding implementation of std::forward. template -RPC_INLINE constexpr T &&forward(typename remove_reference::type &value) { +RPC_ATTRS constexpr T &&forward(typename remove_reference::type &value) { return static_cast(value); } template -RPC_INLINE constexpr T &&forward(typename remove_reference::type &&value) { +RPC_ATTRS constexpr T &&forward(typename remove_reference::type &&value) { return static_cast(value); } struct in_place_t { - RPC_INLINE explicit in_place_t() = default; + RPC_ATTRS explicit in_place_t() = default; }; struct nullopt_t { - RPC_INLINE constexpr explicit nullopt_t() = default; + RPC_ATTRS constexpr explicit nullopt_t() = default; }; constexpr inline in_place_t in_place{}; @@ -80,15 +86,15 @@ template class optional { bool in_use = false; - RPC_INLINE ~OptionalStorage() { reset(); } + RPC_ATTRS ~OptionalStorage() { reset(); } - RPC_INLINE constexpr OptionalStorage() : empty() {} + RPC_ATTRS constexpr OptionalStorage() : empty() {} template - RPC_INLINE constexpr explicit OptionalStorage(in_place_t, Args &&...args) + RPC_ATTRS constexpr explicit OptionalStorage(in_place_t, Args &&...args) : stored_value(forward(args)...) {} - RPC_INLINE constexpr void reset() { + RPC_ATTRS constexpr void reset() { if (in_use) stored_value.~U(); in_use = false; @@ -98,58 +104,58 @@ template class optional { OptionalStorage storage; public: - RPC_INLINE constexpr optional() = default; - RPC_INLINE constexpr optional(nullopt_t) {} + RPC_ATTRS constexpr optional() = default; + RPC_ATTRS constexpr optional(nullopt_t) {} - RPC_INLINE constexpr optional(const T &t) : storage(in_place, t) { + RPC_ATTRS constexpr optional(const T &t) : storage(in_place, t) { storage.in_use = true; } - RPC_INLINE constexpr optional(const optional &) = default; + RPC_ATTRS constexpr optional(const optional &) = default; - RPC_INLINE constexpr optional(T &&t) : storage(in_place, move(t)) { + RPC_ATTRS constexpr optional(T &&t) : storage(in_place, move(t)) { storage.in_use = true; } - RPC_INLINE constexpr optional(optional &&O) = default; + RPC_ATTRS constexpr optional(optional &&O) = default; - RPC_INLINE constexpr optional &operator=(T &&t) { + RPC_ATTRS constexpr optional &operator=(T &&t) { storage = move(t); return *this; } - RPC_INLINE constexpr optional &operator=(optional &&) = default; + RPC_ATTRS constexpr optional &operator=(optional &&) = default; - RPC_INLINE constexpr optional &operator=(const T &t) { + RPC_ATTRS constexpr optional &operator=(const T &t) { storage = t; return *this; } - RPC_INLINE constexpr optional &operator=(const optional &) = default; + RPC_ATTRS constexpr optional &operator=(const optional &) = default; - RPC_INLINE constexpr void reset() { storage.reset(); } + RPC_ATTRS constexpr void reset() { storage.reset(); } - RPC_INLINE constexpr const T &value() const & { return storage.stored_value; } + RPC_ATTRS constexpr const T &value() const & { return storage.stored_value; } - RPC_INLINE constexpr T &value() & { return storage.stored_value; } + RPC_ATTRS constexpr T &value() & { return storage.stored_value; } - RPC_INLINE constexpr explicit operator bool() const { return storage.in_use; } - RPC_INLINE constexpr bool has_value() const { return storage.in_use; } - RPC_INLINE constexpr const T *operator->() const { + RPC_ATTRS constexpr explicit operator bool() const { return storage.in_use; } + RPC_ATTRS constexpr bool has_value() const { return storage.in_use; } + RPC_ATTRS constexpr const T *operator->() const { return &storage.stored_value; } - RPC_INLINE constexpr T *operator->() { return &storage.stored_value; } - RPC_INLINE constexpr const T &operator*() const & { + RPC_ATTRS constexpr T *operator->() { return &storage.stored_value; } + RPC_ATTRS constexpr const T &operator*() const & { return storage.stored_value; } - RPC_INLINE constexpr T &operator*() & { return storage.stored_value; } + RPC_ATTRS constexpr T &operator*() & { return storage.stored_value; } - RPC_INLINE constexpr T &&value() && { return move(storage.stored_value); } - RPC_INLINE constexpr T &&operator*() && { return move(storage.stored_value); } + RPC_ATTRS constexpr T &&value() && { return move(storage.stored_value); } + RPC_ATTRS constexpr T &&operator*() && { return move(storage.stored_value); } }; /// Suspend the thread briefly to assist the thread scheduler during busy loops. -RPC_INLINE void sleep_briefly() { -#if defined(__NVPTX__) +RPC_ATTRS void sleep_briefly() { +#if defined(__NVPTX__) && defined(RPC_TARGET_IS_GPU) if (__nvvm_reflect("__CUDA_ARCH") >= 700) asm("nanosleep.u32 64;" ::: "memory"); -#elif defined(__AMDGPU__) +#elif defined(__AMDGPU__) && defined(RPC_TARGET_IS_GPU) __builtin_amdgcn_s_sleep(2); #elif __has_builtin(__builtin_ia32_pause) __builtin_ia32_pause(); @@ -161,7 +167,7 @@ RPC_INLINE void sleep_briefly() { } /// Conditional to indicate if this process is running on the GPU. -RPC_INLINE constexpr bool is_process_gpu() { +RPC_ATTRS constexpr bool is_process_gpu() { #ifdef RPC_TARGET_IS_GPU return true; #else @@ -170,14 +176,15 @@ RPC_INLINE constexpr bool is_process_gpu() { } /// Wait for all lanes in the group to complete. -RPC_INLINE void sync_lane(uint64_t lane_mask) { +RPC_ATTRS void sync_lane([[maybe_unused]] uint64_t lane_mask) { #ifdef RPC_TARGET_IS_GPU return __gpu_sync_lane(lane_mask); #endif } /// Copies the value from the first active thread to the rest. -RPC_INLINE uint32_t broadcast_value(uint64_t lane_mask, uint32_t x) { +RPC_ATTRS uint32_t broadcast_value([[maybe_unused]] uint64_t lane_mask, + uint32_t x) { #ifdef RPC_TARGET_IS_GPU return __gpu_read_first_lane_u32(lane_mask, x); #else @@ -186,7 +193,7 @@ RPC_INLINE uint32_t broadcast_value(uint64_t lane_mask, uint32_t x) { } /// Returns the number lanes that participate in the RPC interface. -RPC_INLINE uint32_t get_num_lanes() { +RPC_ATTRS uint32_t get_num_lanes() { #ifdef RPC_TARGET_IS_GPU return __gpu_num_lanes(); #else @@ -195,7 +202,7 @@ RPC_INLINE uint32_t get_num_lanes() { } /// Returns the id of the thread inside of an AMD wavefront executing together. -RPC_INLINE uint64_t get_lane_mask() { +RPC_ATTRS uint64_t get_lane_mask() { #ifdef RPC_TARGET_IS_GPU return __gpu_lane_mask(); #else @@ -204,7 +211,7 @@ RPC_INLINE uint64_t get_lane_mask() { } /// Returns the id of the thread inside of an AMD wavefront executing together. -RPC_INLINE uint32_t get_lane_id() { +RPC_ATTRS uint32_t get_lane_id() { #ifdef RPC_TARGET_IS_GPU return __gpu_lane_id(); #else @@ -213,7 +220,7 @@ RPC_INLINE uint32_t get_lane_id() { } /// Conditional that is only true for a single thread in a lane. -RPC_INLINE bool is_first_lane(uint64_t lane_mask) { +RPC_ATTRS bool is_first_lane([[maybe_unused]] uint64_t lane_mask) { #ifdef RPC_TARGET_IS_GPU return __gpu_is_first_in_lane(lane_mask); #else @@ -222,7 +229,7 @@ RPC_INLINE bool is_first_lane(uint64_t lane_mask) { } /// Returns a bitmask of threads in the current lane for which \p x is true. -RPC_INLINE uint64_t ballot(uint64_t lane_mask, bool x) { +RPC_ATTRS uint64_t ballot([[maybe_unused]] uint64_t lane_mask, bool x) { #ifdef RPC_TARGET_IS_GPU return __gpu_ballot(lane_mask, x); #else @@ -232,7 +239,7 @@ RPC_INLINE uint64_t ballot(uint64_t lane_mask, bool x) { /// Return \p val aligned "upwards" according to \p align. template -RPC_INLINE constexpr V align_up(V val, A align) { +RPC_ATTRS constexpr V align_up(V val, A align) { return ((val + V(align) - 1) / V(align)) * V(align); } @@ -240,14 +247,14 @@ RPC_INLINE constexpr V align_up(V val, A align) { /// model. On the GPU stack variables are always private to a lane so we can /// simply use the variable passed in. On the CPU we need to allocate enough /// space for the whole lane and index into it. -template RPC_INLINE V &lane_value(V *val, uint32_t id) { +template RPC_ATTRS V &lane_value(V *val, uint32_t id) { if constexpr (is_process_gpu()) return *val; return val[id]; } /// Advance the \p p by \p bytes. -template RPC_INLINE T *advance(T *ptr, U bytes) { +template RPC_ATTRS T *advance(T *ptr, U bytes) { if constexpr (is_const::value) return reinterpret_cast(reinterpret_cast(ptr) + bytes); @@ -256,11 +263,11 @@ template RPC_INLINE T *advance(T *ptr, U bytes) { } /// Wrapper around the optimal memory copy implementation for the target. -RPC_INLINE void rpc_memcpy(void *dst, const void *src, size_t count) { +RPC_ATTRS void rpc_memcpy(void *dst, const void *src, size_t count) { __builtin_memcpy(dst, src, count); } -template RPC_INLINE constexpr const T &max(const T &a, const T &b) { +template RPC_ATTRS constexpr const T &max(const T &a, const T &b) { return (a < b) ? b : a; } diff --git a/libc/src/CMakeLists.txt b/libc/src/CMakeLists.txt index 02c193e635362..9fc331ad18a39 100644 --- a/libc/src/CMakeLists.txt +++ b/libc/src/CMakeLists.txt @@ -12,7 +12,9 @@ add_subdirectory(stdfix) add_subdirectory(stdio) add_subdirectory(stdlib) add_subdirectory(string) +add_subdirectory(strings) add_subdirectory(wchar) +add_subdirectory(time) if(${LIBC_TARGET_OS} STREQUAL "linux") add_subdirectory(dirent) @@ -32,13 +34,12 @@ if(NOT LLVM_LIBC_FULL_BUILD) return() endif() +add_subdirectory(arpa) add_subdirectory(assert) add_subdirectory(compiler) -add_subdirectory(network) +add_subdirectory(locale) add_subdirectory(search) add_subdirectory(setjmp) add_subdirectory(signal) add_subdirectory(spawn) add_subdirectory(threads) -add_subdirectory(time) -add_subdirectory(locale) diff --git a/libc/src/__support/CMakeLists.txt b/libc/src/__support/CMakeLists.txt index 8f85740f70a06..70ed67c156d1a 100644 --- a/libc/src/__support/CMakeLists.txt +++ b/libc/src/__support/CMakeLists.txt @@ -48,13 +48,19 @@ add_header_library( .freetrie ) -add_header_library( +add_object_library( freelist_heap + SRCS + freelist_heap.cpp HDRS freelist_heap.h + COMPILE_OPTIONS + -DLIBC_FREELIST_MALLOC_SIZE=${LIBC_CONF_FREELIST_MALLOC_BUFFER_SIZE} DEPENDS .block + .freelist .freestore + .freetrie libc.src.__support.CPP.cstddef libc.src.__support.CPP.array libc.src.__support.CPP.optional diff --git a/libc/src/__support/CPP/atomic.h b/libc/src/__support/CPP/atomic.h index 72e7f2adde6a4..287dcac98fbb6 100644 --- a/libc/src/__support/CPP/atomic.h +++ b/libc/src/__support/CPP/atomic.h @@ -9,6 +9,7 @@ #ifndef LLVM_LIBC_SRC___SUPPORT_CPP_ATOMIC_H #define LLVM_LIBC_SRC___SUPPORT_CPP_ATOMIC_H +#include "src/__support/CPP/type_traits/has_unique_object_representations.h" #include "src/__support/macros/attributes.h" #include "src/__support/macros/config.h" #include "src/__support/macros/properties/architectures.h" @@ -40,15 +41,37 @@ enum class MemoryScope : int { }; template struct Atomic { - // For now, we will restrict to only arithmetic types. - static_assert(is_arithmetic_v, "Only arithmetic types can be atomic."); + static_assert(is_trivially_copyable_v && is_copy_constructible_v && + is_move_constructible_v && is_copy_assignable_v && + is_move_assignable_v, + "atomic requires T to be trivially copyable, copy " + "constructible, move constructible, copy assignable, " + "and move assignable."); + + static_assert(cpp::has_unique_object_representations_v, + "atomic in libc only support types whose values has unique " + "object representations."); private: - // The value stored should be appropriately aligned so that - // hardware instructions used to perform atomic operations work - // correctly. - static constexpr int ALIGNMENT = sizeof(T) > alignof(T) ? sizeof(T) - : alignof(T); + // type conversion helper to avoid long c++ style casts + LIBC_INLINE static int order(MemoryOrder mem_ord) { + return static_cast(mem_ord); + } + + LIBC_INLINE static int scope(MemoryScope mem_scope) { + return static_cast(mem_scope); + } + + LIBC_INLINE static T *addressof(T &ref) { return __builtin_addressof(ref); } + + // Require types that are 1, 2, 4, 8, or 16 bytes in length to be aligned to + // at least their size to be potentially used lock-free. + LIBC_INLINE_VAR static constexpr size_t MIN_ALIGNMENT = + (sizeof(T) & (sizeof(T) - 1)) || (sizeof(T) > 16) ? 0 : sizeof(T); + + LIBC_INLINE_VAR static constexpr size_t ALIGNMENT = alignof(T) > MIN_ALIGNMENT + ? alignof(T) + : MIN_ALIGNMENT; public: using value_type = T; @@ -59,139 +82,160 @@ template struct Atomic { // operations should be performed using the atomic methods however. alignas(ALIGNMENT) value_type val; - constexpr Atomic() = default; + LIBC_INLINE constexpr Atomic() = default; // Intializes the value without using atomic operations. - constexpr Atomic(value_type v) : val(v) {} + LIBC_INLINE constexpr Atomic(value_type v) : val(v) {} - Atomic(const Atomic &) = delete; - Atomic &operator=(const Atomic &) = delete; + LIBC_INLINE Atomic(const Atomic &) = delete; + LIBC_INLINE Atomic &operator=(const Atomic &) = delete; // Atomic load. - operator T() { return __atomic_load_n(&val, int(MemoryOrder::SEQ_CST)); } + LIBC_INLINE operator T() { return load(); } - T load(MemoryOrder mem_ord = MemoryOrder::SEQ_CST, - [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { -#if __has_builtin(__scoped_atomic_load_n) - return __scoped_atomic_load_n(&val, int(mem_ord), (int)(mem_scope)); + LIBC_INLINE T + load(MemoryOrder mem_ord = MemoryOrder::SEQ_CST, + [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { + T res; +#if __has_builtin(__scoped_atomic_load) + __scoped_atomic_load(addressof(val), addressof(res), order(mem_ord), + scope(mem_scope)); #else - return __atomic_load_n(&val, int(mem_ord)); + __atomic_load(addressof(val), addressof(res), order(mem_ord)); #endif + return res; } // Atomic store. - T operator=(T rhs) { - __atomic_store_n(&val, rhs, int(MemoryOrder::SEQ_CST)); + LIBC_INLINE T operator=(T rhs) { + store(rhs); return rhs; } - void store(T rhs, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, - [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { -#if __has_builtin(__scoped_atomic_store_n) - __scoped_atomic_store_n(&val, rhs, int(mem_ord), (int)(mem_scope)); + LIBC_INLINE void + store(T rhs, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, + [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { +#if __has_builtin(__scoped_atomic_store) + __scoped_atomic_store(addressof(val), addressof(rhs), order(mem_ord), + scope(mem_scope)); #else - __atomic_store_n(&val, rhs, int(mem_ord)); + __atomic_store(addressof(val), addressof(rhs), order(mem_ord)); #endif } // Atomic compare exchange - bool compare_exchange_strong( + LIBC_INLINE bool compare_exchange_strong( T &expected, T desired, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { - return __atomic_compare_exchange_n(&val, &expected, desired, false, - int(mem_ord), int(mem_ord)); + return __atomic_compare_exchange(addressof(val), addressof(expected), + addressof(desired), false, order(mem_ord), + order(mem_ord)); } // Atomic compare exchange (separate success and failure memory orders) - bool compare_exchange_strong( + LIBC_INLINE bool compare_exchange_strong( T &expected, T desired, MemoryOrder success_order, MemoryOrder failure_order, [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { - return __atomic_compare_exchange_n(&val, &expected, desired, false, - static_cast(success_order), - static_cast(failure_order)); + return __atomic_compare_exchange( + addressof(val), addressof(expected), addressof(desired), false, + order(success_order), order(failure_order)); } // Atomic compare exchange (weak version) - bool compare_exchange_weak( + LIBC_INLINE bool compare_exchange_weak( T &expected, T desired, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { - return __atomic_compare_exchange_n(&val, &expected, desired, true, - static_cast(mem_ord), - static_cast(mem_ord)); + return __atomic_compare_exchange(addressof(val), addressof(expected), + addressof(desired), true, order(mem_ord), + order(mem_ord)); } // Atomic compare exchange (weak version with separate success and failure // memory orders) - bool compare_exchange_weak( + LIBC_INLINE bool compare_exchange_weak( T &expected, T desired, MemoryOrder success_order, MemoryOrder failure_order, [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { - return __atomic_compare_exchange_n(&val, &expected, desired, true, - static_cast(success_order), - static_cast(failure_order)); + return __atomic_compare_exchange( + addressof(val), addressof(expected), addressof(desired), true, + order(success_order), order(failure_order)); } - T exchange(T desired, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, - [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { -#if __has_builtin(__scoped_atomic_exchange_n) - return __scoped_atomic_exchange_n(&val, desired, int(mem_ord), - (int)(mem_scope)); + LIBC_INLINE T + exchange(T desired, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, + [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { + T ret; +#if __has_builtin(__scoped_atomic_exchange) + __scoped_atomic_exchange(addressof(val), addressof(desired), addressof(ret), + order(mem_ord), scope(mem_scope)); #else - return __atomic_exchange_n(&val, desired, int(mem_ord)); + __atomic_exchange(addressof(val), addressof(desired), addressof(ret), + order(mem_ord)); #endif + return ret; } - T fetch_add(T increment, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, - [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { + LIBC_INLINE T + fetch_add(T increment, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, + [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { + static_assert(cpp::is_integral_v, "T must be an integral type."); #if __has_builtin(__scoped_atomic_fetch_add) - return __scoped_atomic_fetch_add(&val, increment, int(mem_ord), - (int)(mem_scope)); + return __scoped_atomic_fetch_add(addressof(val), increment, order(mem_ord), + scope(mem_scope)); #else - return __atomic_fetch_add(&val, increment, int(mem_ord)); + return __atomic_fetch_add(addressof(val), increment, order(mem_ord)); #endif } - T fetch_or(T mask, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, - [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { + LIBC_INLINE T + fetch_or(T mask, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, + [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { + static_assert(cpp::is_integral_v, "T must be an integral type."); #if __has_builtin(__scoped_atomic_fetch_or) - return __scoped_atomic_fetch_or(&val, mask, int(mem_ord), (int)(mem_scope)); + return __scoped_atomic_fetch_or(addressof(val), mask, order(mem_ord), + scope(mem_scope)); #else - return __atomic_fetch_or(&val, mask, int(mem_ord)); + return __atomic_fetch_or(addressof(val), mask, order(mem_ord)); #endif } - T fetch_and(T mask, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, - [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { + LIBC_INLINE T + fetch_and(T mask, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, + [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { + static_assert(cpp::is_integral_v, "T must be an integral type."); #if __has_builtin(__scoped_atomic_fetch_and) - return __scoped_atomic_fetch_and(&val, mask, int(mem_ord), - (int)(mem_scope)); + return __scoped_atomic_fetch_and(addressof(val), mask, order(mem_ord), + scope(mem_scope)); #else - return __atomic_fetch_and(&val, mask, int(mem_ord)); + return __atomic_fetch_and(addressof(val), mask, order(mem_ord)); #endif } - T fetch_sub(T decrement, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, - [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { + LIBC_INLINE T + fetch_sub(T decrement, MemoryOrder mem_ord = MemoryOrder::SEQ_CST, + [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { + static_assert(cpp::is_integral_v, "T must be an integral type."); #if __has_builtin(__scoped_atomic_fetch_sub) - return __scoped_atomic_fetch_sub(&val, decrement, int(mem_ord), - (int)(mem_scope)); + return __scoped_atomic_fetch_sub(addressof(val), decrement, order(mem_ord), + scope(mem_scope)); #else - return __atomic_fetch_sub(&val, decrement, int(mem_ord)); + return __atomic_fetch_sub(addressof(val), decrement, order(mem_ord)); #endif } // Set the value without using an atomic operation. This is useful // in initializing atomic values without a constructor. - void set(T rhs) { val = rhs; } + LIBC_INLINE void set(T rhs) { val = rhs; } }; // Issue a thread fence with the given memory ordering. -LIBC_INLINE void atomic_thread_fence([[maybe_unused]] MemoryOrder mem_ord) { -// The NVPTX backend currently does not support atomic thread fences so we use a -// full system fence instead. -#ifdef LIBC_TARGET_ARCH_IS_NVPTX - __nvvm_membar_sys(); +LIBC_INLINE void atomic_thread_fence( + MemoryOrder mem_ord, + [[maybe_unused]] MemoryScope mem_scope = MemoryScope::DEVICE) { +#if __has_builtin(__scoped_atomic_thread_fence) + __scoped_atomic_thread_fence(static_cast(mem_ord), + static_cast(mem_scope)); #else __atomic_thread_fence(static_cast(mem_ord)); #endif diff --git a/libc/src/__support/CPP/type_traits.h b/libc/src/__support/CPP/type_traits.h index d50b6612656db..910cebbb8d059 100644 --- a/libc/src/__support/CPP/type_traits.h +++ b/libc/src/__support/CPP/type_traits.h @@ -18,6 +18,7 @@ #include "src/__support/CPP/type_traits/decay.h" #include "src/__support/CPP/type_traits/enable_if.h" #include "src/__support/CPP/type_traits/false_type.h" +#include "src/__support/CPP/type_traits/has_unique_object_representations.h" #include "src/__support/CPP/type_traits/integral_constant.h" #include "src/__support/CPP/type_traits/invoke.h" #include "src/__support/CPP/type_traits/invoke_result.h" @@ -28,6 +29,8 @@ #include "src/__support/CPP/type_traits/is_const.h" #include "src/__support/CPP/type_traits/is_constant_evaluated.h" #include "src/__support/CPP/type_traits/is_convertible.h" +#include "src/__support/CPP/type_traits/is_copy_assignable.h" +#include "src/__support/CPP/type_traits/is_copy_constructible.h" #include "src/__support/CPP/type_traits/is_destructible.h" #include "src/__support/CPP/type_traits/is_enum.h" #include "src/__support/CPP/type_traits/is_fixed_point.h" @@ -36,6 +39,8 @@ #include "src/__support/CPP/type_traits/is_integral.h" #include "src/__support/CPP/type_traits/is_lvalue_reference.h" #include "src/__support/CPP/type_traits/is_member_pointer.h" +#include "src/__support/CPP/type_traits/is_move_assignable.h" +#include "src/__support/CPP/type_traits/is_move_constructible.h" #include "src/__support/CPP/type_traits/is_null_pointer.h" #include "src/__support/CPP/type_traits/is_object.h" #include "src/__support/CPP/type_traits/is_pointer.h" diff --git a/libc/src/__support/CPP/type_traits/has_unique_object_representations.h b/libc/src/__support/CPP/type_traits/has_unique_object_representations.h new file mode 100644 index 0000000000000..639fb69d27203 --- /dev/null +++ b/libc/src/__support/CPP/type_traits/has_unique_object_representations.h @@ -0,0 +1,30 @@ +//===-- has_unique_object_representations type_traits ------------*- 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_CPP_TYPE_TRAITS_HAS_UNIQUE_OBJECT_REPRESENTATIONS_H +#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_HAS_UNIQUE_OBJECT_REPRESENTATIONS_H + +#include "src/__support/CPP/type_traits/integral_constant.h" +#include "src/__support/CPP/type_traits/remove_all_extents.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { +namespace cpp { + +template +struct has_unique_object_representations + : public integral_constant)> {}; + +template +LIBC_INLINE_VAR constexpr bool has_unique_object_representations_v = + has_unique_object_representations::value; + +} // namespace cpp +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_HAS_UNIQUE_OBJECT_REPRESENTATIONS_H diff --git a/libc/src/__support/CPP/type_traits/is_copy_assignable.h b/libc/src/__support/CPP/type_traits/is_copy_assignable.h new file mode 100644 index 0000000000000..9beb93d14668d --- /dev/null +++ b/libc/src/__support/CPP/type_traits/is_copy_assignable.h @@ -0,0 +1,32 @@ +//===-- is_copy_assignable type_traits --------------------------*- 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_CPP_TYPE_TRAITS_IS_COPY_ASSIGNABLE_H +#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_COPY_ASSIGNABLE_H + +#include "src/__support/CPP/type_traits/add_lvalue_reference.h" +#include "src/__support/CPP/type_traits/integral_constant.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { +namespace cpp { + +// is copy assignable +template +struct is_copy_assignable + : public integral_constant< + bool, __is_assignable(cpp::add_lvalue_reference_t, + cpp::add_lvalue_reference_t)> {}; + +template +LIBC_INLINE_VAR constexpr bool is_copy_assignable_v = + is_copy_assignable::value; + +} // namespace cpp +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_COPY_ASSIGNABLE_H diff --git a/libc/src/__support/CPP/type_traits/is_copy_constructible.h b/libc/src/__support/CPP/type_traits/is_copy_constructible.h new file mode 100644 index 0000000000000..d8eb9ad3507ee --- /dev/null +++ b/libc/src/__support/CPP/type_traits/is_copy_constructible.h @@ -0,0 +1,31 @@ +//===-- is_copy_constructible type_traits -----------------------*- 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_CPP_TYPE_TRAITS_IS_COPY_CONSTRUCTIBLE_H +#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_COPY_CONSTRUCTIBLE_H + +#include "src/__support/CPP/type_traits/add_lvalue_reference.h" +#include "src/__support/CPP/type_traits/integral_constant.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { +namespace cpp { + +// is copy constructible +template +struct is_copy_constructible + : public integral_constant< + bool, __is_constructible(T, cpp::add_lvalue_reference_t)> {}; + +template +LIBC_INLINE_VAR constexpr bool is_copy_constructible_v = + is_copy_constructible::value; + +} // namespace cpp +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_COPY_CONSTRUCTIBLE_H diff --git a/libc/src/__support/CPP/type_traits/is_move_assignable.h b/libc/src/__support/CPP/type_traits/is_move_assignable.h new file mode 100644 index 0000000000000..a788bd9074e32 --- /dev/null +++ b/libc/src/__support/CPP/type_traits/is_move_assignable.h @@ -0,0 +1,33 @@ +//===-- is_move_assignable type_traits --------------------------*- 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_CPP_TYPE_TRAITS_IS_MOVE_ASSIGNABLE_H +#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_MOVE_ASSIGNABLE_H + +#include "src/__support/CPP/type_traits/add_lvalue_reference.h" +#include "src/__support/CPP/type_traits/add_rvalue_reference.h" +#include "src/__support/CPP/type_traits/integral_constant.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { +namespace cpp { + +// is move assignable +template +struct is_move_assignable + : public integral_constant, + cpp::add_rvalue_reference_t)> {}; + +template +LIBC_INLINE_VAR constexpr bool is_move_assignable_v = + is_move_assignable::value; + +} // namespace cpp +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_MOVE_ASSIGNABLE_H diff --git a/libc/src/__support/CPP/type_traits/is_move_constructible.h b/libc/src/__support/CPP/type_traits/is_move_constructible.h new file mode 100644 index 0000000000000..c898960546258 --- /dev/null +++ b/libc/src/__support/CPP/type_traits/is_move_constructible.h @@ -0,0 +1,31 @@ +//===-- is_move_constructible type_traits ------------------------*- 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_CPP_TYPE_TRAITS_IS_MOVE_CONSTRUCTIBLE_H +#define LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_MOVE_CONSTRUCTIBLE_H + +#include "src/__support/CPP/type_traits/add_rvalue_reference.h" +#include "src/__support/CPP/type_traits/integral_constant.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { +namespace cpp { + +// is move constructible +template +struct is_move_constructible + : public integral_constant)> {}; + +template +LIBC_INLINE_VAR constexpr bool is_move_constructible_v = + is_move_constructible::value; + +} // namespace cpp +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC___SUPPORT_CPP_TYPE_TRAITS_IS_MOVE_CONSTRUCTIBLE_H diff --git a/libc/src/__support/CPP/type_traits/is_trivially_copyable.h b/libc/src/__support/CPP/type_traits/is_trivially_copyable.h index 68e56c8547834..a3e786fe1d141 100644 --- a/libc/src/__support/CPP/type_traits/is_trivially_copyable.h +++ b/libc/src/__support/CPP/type_traits/is_trivially_copyable.h @@ -19,6 +19,10 @@ template struct is_trivially_copyable : public integral_constant {}; +template +LIBC_INLINE_VAR constexpr bool is_trivially_copyable_v = + is_trivially_copyable::value; + } // namespace cpp } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/FPUtil/aarch64/FEnvImpl.h b/libc/src/__support/FPUtil/aarch64/FEnvImpl.h index 3cea9772154fc..18b0631324f8f 100644 --- a/libc/src/__support/FPUtil/aarch64/FEnvImpl.h +++ b/libc/src/__support/FPUtil/aarch64/FEnvImpl.h @@ -26,7 +26,6 @@ namespace LIBC_NAMESPACE_DECL { namespace fputil { - struct FEnv { struct FPState { uint32_t ControlWord; @@ -42,11 +41,11 @@ struct FEnv { static constexpr uint32_t DOWNWARD = 0x2; static constexpr uint32_t TOWARDZERO = 0x3; - static constexpr uint32_t INVALID = 0x1; - static constexpr uint32_t DIVBYZERO = 0x2; - static constexpr uint32_t OVERFLOW = 0x4; - static constexpr uint32_t UNDERFLOW = 0x8; - static constexpr uint32_t INEXACT = 0x10; + static constexpr uint32_t INVALID_F = 0x1; + static constexpr uint32_t DIVBYZERO_F = 0x2; + static constexpr uint32_t OVERFLOW_F = 0x4; + static constexpr uint32_t UNDERFLOW_F = 0x8; + static constexpr uint32_t INEXACT_F = 0x10; // Zero-th bit is the first bit. static constexpr uint32_t RoundingControlBitPosition = 22; @@ -54,19 +53,19 @@ struct FEnv { static constexpr uint32_t ExceptionControlFlagsBitPosition = 8; LIBC_INLINE static uint32_t getStatusValueForExcept(int excepts) { - return ((excepts & FE_INVALID) ? INVALID : 0) | - ((excepts & FE_DIVBYZERO) ? DIVBYZERO : 0) | - ((excepts & FE_OVERFLOW) ? OVERFLOW : 0) | - ((excepts & FE_UNDERFLOW) ? UNDERFLOW : 0) | - ((excepts & FE_INEXACT) ? INEXACT : 0); + return ((excepts & FE_INVALID) ? INVALID_F : 0) | + ((excepts & FE_DIVBYZERO) ? DIVBYZERO_F : 0) | + ((excepts & FE_OVERFLOW) ? OVERFLOW_F : 0) | + ((excepts & FE_UNDERFLOW) ? UNDERFLOW_F : 0) | + ((excepts & FE_INEXACT) ? INEXACT_F : 0); } LIBC_INLINE static int exceptionStatusToMacro(uint32_t status) { - return ((status & INVALID) ? FE_INVALID : 0) | - ((status & DIVBYZERO) ? FE_DIVBYZERO : 0) | - ((status & OVERFLOW) ? FE_OVERFLOW : 0) | - ((status & UNDERFLOW) ? FE_UNDERFLOW : 0) | - ((status & INEXACT) ? FE_INEXACT : 0); + return ((status & INVALID_F) ? FE_INVALID : 0) | + ((status & DIVBYZERO_F) ? FE_DIVBYZERO : 0) | + ((status & OVERFLOW_F) ? FE_OVERFLOW : 0) | + ((status & UNDERFLOW_F) ? FE_UNDERFLOW : 0) | + ((status & INEXACT_F) ? FE_INEXACT : 0); } static uint32_t getControlWord() { @@ -171,36 +170,36 @@ LIBC_INLINE int raise_except(int excepts) { uint32_t toRaise = FEnv::getStatusValueForExcept(excepts); int result = 0; - if (toRaise & FEnv::INVALID) { + if (toRaise & FEnv::INVALID_F) { divfunc(zero, zero); uint32_t statusWord = FEnv::getStatusWord(); if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) & - FEnv::INVALID)) + FEnv::INVALID_F)) result = -1; } - if (toRaise & FEnv::DIVBYZERO) { + if (toRaise & FEnv::DIVBYZERO_F) { divfunc(one, zero); uint32_t statusWord = FEnv::getStatusWord(); if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) & - FEnv::DIVBYZERO)) + FEnv::DIVBYZERO_F)) result = -1; } - if (toRaise & FEnv::OVERFLOW) { + if (toRaise & FEnv::OVERFLOW_F) { divfunc(largeValue, smallValue); uint32_t statusWord = FEnv::getStatusWord(); if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) & - FEnv::OVERFLOW)) + FEnv::OVERFLOW_F)) result = -1; } - if (toRaise & FEnv::UNDERFLOW) { + if (toRaise & FEnv::UNDERFLOW_F) { divfunc(smallValue, largeValue); uint32_t statusWord = FEnv::getStatusWord(); if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) & - FEnv::UNDERFLOW)) + FEnv::UNDERFLOW_F)) result = -1; } - if (toRaise & FEnv::INEXACT) { + if (toRaise & FEnv::INEXACT_F) { float two = 2.0f; float three = 3.0f; // 2.0 / 3.0 cannot be represented exactly in any radix 2 floating point @@ -208,7 +207,7 @@ LIBC_INLINE int raise_except(int excepts) { divfunc(two, three); uint32_t statusWord = FEnv::getStatusWord(); if (!((statusWord >> FEnv::ExceptionStatusFlagsBitPosition) & - FEnv::INEXACT)) + FEnv::INEXACT_F)) result = -1; } return result; @@ -278,7 +277,6 @@ LIBC_INLINE int set_env(const fenv_t *envp) { FEnv::writeStatusWord(state->StatusWord); return 0; } - } // namespace fputil } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/complex_type.h b/libc/src/__support/complex_type.h index d6b5eec8fd6b2..5dadfd20a0051 100644 --- a/libc/src/__support/complex_type.h +++ b/libc/src/__support/complex_type.h @@ -10,11 +10,70 @@ #define LLVM_LIBC_SRC___SUPPORT_COMPLEX_TYPE_H #include "src/__support/macros/config.h" +#include "src/__support/macros/properties/complex_types.h" +#include "src/__support/macros/properties/types.h" namespace LIBC_NAMESPACE_DECL { template struct Complex { T real; T imag; }; + +template struct make_complex; + +template <> struct make_complex { + using type = _Complex float; +}; +template <> struct make_complex { + using type = _Complex double; +}; +template <> struct make_complex { + using type = _Complex long double; +}; + +#if defined(LIBC_TYPES_HAS_CFLOAT16) +template <> struct make_complex { + using type = cfloat16; +}; +#endif +#ifdef LIBC_TYPES_CFLOAT128_IS_NOT_COMPLEX_LONG_DOUBLE +template <> struct make_complex { + using type = cfloat128; +}; +#endif + +template using make_complex_t = typename make_complex::type; + +template struct make_real; + +template <> struct make_real<_Complex float> { + using type = float; +}; +template <> struct make_real<_Complex double> { + using type = double; +}; +template <> struct make_real<_Complex long double> { + using type = long double; +}; + +#if defined(LIBC_TYPES_HAS_CFLOAT16) +template <> struct make_real { + using type = float16; +}; +#endif +#ifdef LIBC_TYPES_CFLOAT128_IS_NOT_COMPLEX_LONG_DOUBLE +template <> struct make_real { + using type = float128; +}; +#endif + +template using make_real_t = typename make_real::type; + +template LIBC_INLINE constexpr T conjugate(T c) { + Complex> c_c = cpp::bit_cast>>(c); + c_c.imag = -c_c.imag; + return cpp::bit_cast(c_c); +} + } // namespace LIBC_NAMESPACE_DECL #endif // LLVM_LIBC_SRC___SUPPORT_COMPLEX_TYPE_H diff --git a/libc/src/__support/freelist_heap.cpp b/libc/src/__support/freelist_heap.cpp new file mode 100644 index 0000000000000..4deb0e0f09e22 --- /dev/null +++ b/libc/src/__support/freelist_heap.cpp @@ -0,0 +1,19 @@ +//===-- Implementation for freelist_heap ----------------------------------===// +// +// 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/freelist_heap.h" +#include "src/__support/macros/config.h" + +#include + +namespace LIBC_NAMESPACE_DECL { + +static LIBC_CONSTINIT FreeListHeap freelist_heap_symbols; +FreeListHeap *freelist_heap = &freelist_heap_symbols; + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/macros/properties/complex_types.h b/libc/src/__support/macros/properties/complex_types.h index 3f4a7646649c6..ede4d6b7c7d9d 100644 --- a/libc/src/__support/macros/properties/complex_types.h +++ b/libc/src/__support/macros/properties/complex_types.h @@ -22,4 +22,9 @@ // LIBC_TYPES_HAS_CFLOAT128 and 'cfloat128' type are provided by // "include/llvm-libc-types/cfloat128.h" +#if defined(LIBC_TYPES_HAS_CFLOAT128) && \ + !defined(LIBC_TYPES_CFLOAT128_IS_COMPLEX_LONG_DOUBLE) +#define LIBC_TYPES_CFLOAT128_IS_NOT_COMPLEX_LONG_DOUBLE +#endif + #endif // LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_CTYPES_H diff --git a/libc/src/__support/macros/properties/os.h b/libc/src/__support/macros/properties/os.h index 1c8fd5721ce67..807ce1812735c 100644 --- a/libc/src/__support/macros/properties/os.h +++ b/libc/src/__support/macros/properties/os.h @@ -25,18 +25,6 @@ #define LIBC_TARGET_OS_IS_WINDOWS #endif -#if (defined(__apple__) || defined(__APPLE__) || defined(__MACH__)) -// From https://stackoverflow.com/a/49560690 -#include "TargetConditionals.h" -#if defined(TARGET_OS_OSX) -#define LIBC_TARGET_OS_IS_MACOS -#endif -#if defined(TARGET_OS_IPHONE) -// This is set for any non-Mac Apple products (IOS, TV, WATCH) -#define LIBC_TARGET_OS_IS_IPHONE -#endif -#endif - #if defined(__Fuchsia__) #define LIBC_TARGET_OS_IS_FUCHSIA #endif diff --git a/libc/src/__support/macros/properties/types.h b/libc/src/__support/macros/properties/types.h index 30c742c007ca1..6293b9d4d292a 100644 --- a/libc/src/__support/macros/properties/types.h +++ b/libc/src/__support/macros/properties/types.h @@ -31,6 +31,11 @@ #define LIBC_TYPES_LONG_DOUBLE_IS_DOUBLE_DOUBLE #endif +#if defined(LIBC_TYPES_HAS_FLOAT128) && \ + !defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128) +#define LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +#endif + // int64 / uint64 support #if defined(UINT64_MAX) #define LIBC_TYPES_HAS_INT64 diff --git a/libc/src/__support/time/CMakeLists.txt b/libc/src/__support/time/CMakeLists.txt index 89ddffb099388..8247e792e8410 100644 --- a/libc/src/__support/time/CMakeLists.txt +++ b/libc/src/__support/time/CMakeLists.txt @@ -1,7 +1,3 @@ -if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) - add_subdirectory(${LIBC_TARGET_OS}) -endif() - add_header_library( units HDRS @@ -10,3 +6,16 @@ add_header_library( libc.src.__support.common libc.hdr.types.time_t ) + +if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) + add_subdirectory(${LIBC_TARGET_OS}) +else() + return() +endif() + +add_object_library( + clock_gettime + ALIAS + DEPENDS + libc.src.__support.time.${LIBC_TARGET_OS}.clock_gettime +) diff --git a/libc/src/__support/time/linux/clock_gettime.h b/libc/src/__support/time/clock_gettime.h similarity index 72% rename from libc/src/__support/time/linux/clock_gettime.h rename to libc/src/__support/time/clock_gettime.h index f7f996ce7c197..584bf546cd60c 100644 --- a/libc/src/__support/time/linux/clock_gettime.h +++ b/libc/src/__support/time/clock_gettime.h @@ -6,21 +6,17 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_CLOCK_GETTIME_H -#define LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_CLOCK_GETTIME_H +#ifndef LLVM_LIBC_SRC___SUPPORT_TIME_CLOCK_GETTIME_H +#define LLVM_LIBC_SRC___SUPPORT_TIME_CLOCK_GETTIME_H #include "hdr/types/clockid_t.h" #include "hdr/types/struct_timespec.h" #include "src/__support/error_or.h" -#if defined(SYS_clock_gettime64) -#include -#endif - namespace LIBC_NAMESPACE_DECL { namespace internal { ErrorOr clock_gettime(clockid_t clockid, timespec *ts); } // namespace internal } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_CLOCK_GETTIME_H +#endif // LLVM_LIBC_SRC___SUPPORT_TIME_CLOCK_GETTIME_H diff --git a/libc/src/__support/time/gpu/CMakeLists.txt b/libc/src/__support/time/gpu/CMakeLists.txt new file mode 100644 index 0000000000000..fc465e0cea25f --- /dev/null +++ b/libc/src/__support/time/gpu/CMakeLists.txt @@ -0,0 +1,22 @@ +add_object_library( + time_utils + SRCS + time_utils.cpp + HDRS + time_utils.h + DEPENDS + libc.hdr.types.clock_t + libc.hdr.time_macros +) + +add_object_library( + clock_gettime + SRCS + clock_gettime.cpp + HDRS + ../clock_gettime.h + DEPENDS + libc.hdr.types.clockid_t + libc.hdr.types.struct_timespec + .time_utils +) diff --git a/libc/src/__support/time/gpu/clock_gettime.cpp b/libc/src/__support/time/gpu/clock_gettime.cpp new file mode 100644 index 0000000000000..cede72a1f35da --- /dev/null +++ b/libc/src/__support/time/gpu/clock_gettime.cpp @@ -0,0 +1,33 @@ +//===---------- GPU implementation of the clock_gettime function ----------===// +// +// 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/time/clock_gettime.h" + +#include "src/__support/common.h" +#include "src/__support/macros/config.h" +#include "src/__support/time/clock_gettime.h" +#include "src/__support/time/gpu/time_utils.h" + +namespace LIBC_NAMESPACE_DECL { +namespace internal { +constexpr uint64_t TICKS_PER_SEC = 1000000000UL; + +ErrorOr clock_gettime(clockid_t clockid, timespec *ts) { + if (clockid != CLOCK_MONOTONIC || !ts) + return cpp::unexpected(-1); + + uint64_t ns_per_tick = TICKS_PER_SEC / GPU_CLOCKS_PER_SEC; + uint64_t ticks = gpu::fixed_frequency_clock(); + + ts->tv_nsec = (ticks * ns_per_tick) % TICKS_PER_SEC; + ts->tv_sec = (ticks * ns_per_tick) / TICKS_PER_SEC; + + return 0; +} +} // namespace internal +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/time/gpu/time_utils.cpp b/libc/src/__support/time/gpu/time_utils.cpp similarity index 100% rename from libc/src/time/gpu/time_utils.cpp rename to libc/src/__support/time/gpu/time_utils.cpp diff --git a/libc/src/time/gpu/time_utils.h b/libc/src/__support/time/gpu/time_utils.h similarity index 100% rename from libc/src/time/gpu/time_utils.h rename to libc/src/__support/time/gpu/time_utils.h diff --git a/libc/src/__support/time/linux/CMakeLists.txt b/libc/src/__support/time/linux/CMakeLists.txt index 94ed09e652152..6fec7eeba99ad 100644 --- a/libc/src/__support/time/linux/CMakeLists.txt +++ b/libc/src/__support/time/linux/CMakeLists.txt @@ -1,7 +1,7 @@ add_object_library( clock_gettime HDRS - clock_gettime.h + ../clock_gettime.h SRCS clock_gettime.cpp DEPENDS diff --git a/libc/src/__support/time/linux/clock_conversion.h b/libc/src/__support/time/linux/clock_conversion.h index 7a52873263a14..ac5357d308d7c 100644 --- a/libc/src/__support/time/linux/clock_conversion.h +++ b/libc/src/__support/time/linux/clock_conversion.h @@ -10,7 +10,7 @@ #define LLVM_LIBC_SRC___SUPPORT_TIME_LINUX_CLOCK_CONVERSION_H #include "src/__support/macros/config.h" -#include "src/__support/time/linux/clock_gettime.h" +#include "src/__support/time/clock_gettime.h" #include "src/__support/time/units.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/__support/time/linux/clock_gettime.cpp b/libc/src/__support/time/linux/clock_gettime.cpp index 3a0eca417724a..944fc0a2b80fe 100644 --- a/libc/src/__support/time/linux/clock_gettime.cpp +++ b/libc/src/__support/time/linux/clock_gettime.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/__support/time/linux/clock_gettime.h" +#include "src/__support/time/clock_gettime.h" #include "hdr/types/clockid_t.h" #include "hdr/types/struct_timespec.h" #include "src/__support/OSUtil/linux/vdso.h" diff --git a/libc/src/__support/time/windows/CMakeLists.txt b/libc/src/__support/time/windows/CMakeLists.txt new file mode 100644 index 0000000000000..dd0ac2f2f79ae --- /dev/null +++ b/libc/src/__support/time/windows/CMakeLists.txt @@ -0,0 +1,26 @@ +add_header_library( + performance_counter + HDRS + performance_counter.h + DEPENDS + libc.src.__support.CPP.atomic + libc.src.__support.common +) + +add_object_library( + clock_gettime + HDRS + ../clock_gettime.h + SRCS + clock_gettime.cpp + DEPENDS + .performance_counter + libc.hdr.types.struct_timespec + libc.hdr.types.clockid_t + libc.hdr.errno_macros + libc.src.__support.common + libc.src.__support.error_or + libc.src.__support.OSUtil.osutil + libc.src.__support.CPP.atomic + libc.src.__support.CPP.limits +) diff --git a/libc/src/__support/time/windows/clock_gettime.cpp b/libc/src/__support/time/windows/clock_gettime.cpp new file mode 100644 index 0000000000000..813eae0df9705 --- /dev/null +++ b/libc/src/__support/time/windows/clock_gettime.cpp @@ -0,0 +1,134 @@ +//===--- clock_gettime windows implementation -------------------*- 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 "hdr/time_macros.h" + +#include "src/__support/CPP/atomic.h" +#include "src/__support/CPP/bit.h" +#include "src/__support/CPP/limits.h" +#include "src/__support/macros/optimization.h" +#include "src/__support/time/clock_gettime.h" +#include "src/__support/time/units.h" +#include "src/__support/time/windows/performance_counter.h" + +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include + +namespace LIBC_NAMESPACE_DECL { +namespace internal { +ErrorOr clock_gettime(clockid_t clockid, timespec *ts) { + using namespace time_units; + constexpr unsigned long long HNS_PER_SEC = 1_s_ns / 100ULL; + constexpr long long SEC_LIMIT = + cpp::numeric_limitstv_sec)>::max(); + ErrorOr ret = 0; + switch (clockid) { + default: + ret = cpp::unexpected(EINVAL); + break; + + case CLOCK_MONOTONIC: { + // see + // https://learn.microsoft.com/en-us/windows/win32/sysinfo/acquiring-high-resolution-time-stamps + // Is the performance counter monotonic (non-decreasing)? + // Yes. performance_counter does not go backward. + [[clang::uninitialized]] LARGE_INTEGER buffer; + // On systems that run Windows XP or later, the function will always + // succeed and will thus never return zero. + ::QueryPerformanceCounter(&buffer); + long long freq = performance_counter::get_ticks_per_second(); + long long ticks = buffer.QuadPart; + long long tv_sec = ticks / freq; + long long tv_nsec = (ticks % freq) * 1_s_ns / freq; + if (LIBC_UNLIKELY(tv_sec > SEC_LIMIT)) { + ret = cpp::unexpected(EOVERFLOW); + break; + } + ts->tv_sec = static_casttv_sec)>(tv_sec); + ts->tv_nsec = static_casttv_nsec)>(tv_nsec); + break; + } + case CLOCK_REALTIME: { + // https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimepreciseasfiletime + // GetSystemTimePreciseAsFileTime + // This function is best suited for high-resolution time-of-day + // measurements, or time stamps that are synchronized to UTC + [[clang::uninitialized]] FILETIME file_time; + [[clang::uninitialized]] ULARGE_INTEGER time; + ::GetSystemTimePreciseAsFileTime(&file_time); + time.LowPart = file_time.dwLowDateTime; + time.HighPart = file_time.dwHighDateTime; + + // adjust to POSIX epoch (from Jan 1, 1601 to Jan 1, 1970) + constexpr unsigned long long POSIX_TIME_SHIFT = + (11644473600ULL * HNS_PER_SEC); + if (LIBC_UNLIKELY(POSIX_TIME_SHIFT > time.QuadPart)) { + ret = cpp::unexpected(EOVERFLOW); + break; + } + time.QuadPart -= (11644473600ULL * HNS_PER_SEC); + unsigned long long tv_sec = time.QuadPart / HNS_PER_SEC; + unsigned long long tv_nsec = (time.QuadPart % HNS_PER_SEC) * 100ULL; + if (LIBC_UNLIKELY(tv_sec > SEC_LIMIT)) { + ret = cpp::unexpected(EOVERFLOW); + break; + } + ts->tv_sec = static_casttv_sec)>(tv_sec); + ts->tv_nsec = static_casttv_nsec)>(tv_nsec); + break; + } + case CLOCK_PROCESS_CPUTIME_ID: + case CLOCK_THREAD_CPUTIME_ID: { + [[clang::uninitialized]] FILETIME creation_time; + [[clang::uninitialized]] FILETIME exit_time; + [[clang::uninitialized]] FILETIME kernel_time; + [[clang::uninitialized]] FILETIME user_time; + bool success; + if (clockid == CLOCK_PROCESS_CPUTIME_ID) { + // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes + success = ::GetProcessTimes(::GetCurrentProcess(), &creation_time, + &exit_time, &kernel_time, &user_time); + } else { + // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreadtimes + success = ::GetThreadTimes(::GetCurrentThread(), &creation_time, + &exit_time, &kernel_time, &user_time); + } + if (!success) { + ret = cpp::unexpected(EINVAL); + break; + } + // https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-filetime + // It is not recommended that you add and subtract values from the FILETIME + // structure to obtain relative times. Instead, you should copy the low- and + // high-order parts of the file time to a ULARGE_INTEGER structure, perform + // 64-bit arithmetic on the QuadPart member, and copy the LowPart and + // HighPart members into the FILETIME structure. + auto kernel_time_hns = cpp::bit_cast(kernel_time); + auto user_time_hns = cpp::bit_cast(user_time); + unsigned long long total_time_hns = + kernel_time_hns.QuadPart + user_time_hns.QuadPart; + + unsigned long long tv_sec = total_time_hns / HNS_PER_SEC; + unsigned long long tv_nsec = (total_time_hns % HNS_PER_SEC) * 100ULL; + + if (LIBC_UNLIKELY(tv_sec > SEC_LIMIT)) { + ret = cpp::unexpected(EOVERFLOW); + break; + } + + ts->tv_sec = static_casttv_sec)>(tv_sec); + ts->tv_nsec = static_casttv_nsec)>(tv_nsec); + + break; + } + } + return ret; +} +} // namespace internal +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/__support/time/windows/performance_counter.h b/libc/src/__support/time/windows/performance_counter.h new file mode 100644 index 0000000000000..3df81b3efff40 --- /dev/null +++ b/libc/src/__support/time/windows/performance_counter.h @@ -0,0 +1,35 @@ +//===--- Cached Performance Counter Frequency ----------------------------===// +// +// 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/CPP/atomic.h" +#include "src/__support/common.h" + +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include + +namespace LIBC_NAMESPACE_DECL { +namespace performance_counter { +LIBC_INLINE long long get_ticks_per_second() { + static cpp::Atomic frequency = 0; + // Relaxed ordering is enough. It is okay to record the frequency multiple + // times. The store operation itself is atomic and the value must propagate + // as required by cache coherence. + auto freq = frequency.load(cpp::MemoryOrder::RELAXED); + if (!freq) { + [[clang::uninitialized]] LARGE_INTEGER buffer; + // On systems that run Windows XP or later, the function will always + // succeed and will thus never return zero. + ::QueryPerformanceFrequency(&buffer); + frequency.store(buffer.QuadPart, cpp::MemoryOrder::RELAXED); + return buffer.QuadPart; + } + return freq; +} +} // namespace performance_counter +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/arpa/CMakeLists.txt b/libc/src/arpa/CMakeLists.txt new file mode 100644 index 0000000000000..5c89828860ff8 --- /dev/null +++ b/libc/src/arpa/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(inet) diff --git a/libc/src/network/CMakeLists.txt b/libc/src/arpa/inet/CMakeLists.txt similarity index 100% rename from libc/src/network/CMakeLists.txt rename to libc/src/arpa/inet/CMakeLists.txt diff --git a/libc/src/network/htonl.cpp b/libc/src/arpa/inet/htonl.cpp similarity index 95% rename from libc/src/network/htonl.cpp rename to libc/src/arpa/inet/htonl.cpp index 681786adea68a..fb0404a26a244 100644 --- a/libc/src/network/htonl.cpp +++ b/libc/src/arpa/inet/htonl.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/network/htonl.h" +#include "src/arpa/inet/htonl.h" #include "src/__support/common.h" #include "src/__support/endian_internal.h" #include "src/__support/macros/config.h" diff --git a/libc/src/network/htonl.h b/libc/src/arpa/inet/htonl.h similarity index 81% rename from libc/src/network/htonl.h rename to libc/src/arpa/inet/htonl.h index 14217310a2271..e444972c771ea 100644 --- a/libc/src/network/htonl.h +++ b/libc/src/arpa/inet/htonl.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_NETWORK_HTONL_H -#define LLVM_LIBC_SRC_NETWORK_HTONL_H +#ifndef LLVM_LIBC_SRC_ARPA_INET_HTONL_H +#define LLVM_LIBC_SRC_ARPA_INET_HTONL_H #include "src/__support/macros/config.h" #include @@ -18,4 +18,4 @@ uint32_t htonl(uint32_t hostlong); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_NETWORK_HTONL_H +#endif // LLVM_LIBC_SRC_ARPA_INET_HTONL_H diff --git a/libc/src/network/htons.cpp b/libc/src/arpa/inet/htons.cpp similarity index 95% rename from libc/src/network/htons.cpp rename to libc/src/arpa/inet/htons.cpp index 675f53cf4a0ad..1fcbbdf67deb0 100644 --- a/libc/src/network/htons.cpp +++ b/libc/src/arpa/inet/htons.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/network/htons.h" +#include "src/arpa/inet/htons.h" #include "src/__support/common.h" #include "src/__support/endian_internal.h" #include "src/__support/macros/config.h" diff --git a/libc/src/network/htons.h b/libc/src/arpa/inet/htons.h similarity index 81% rename from libc/src/network/htons.h rename to libc/src/arpa/inet/htons.h index 8f5c68a0a60a8..35c2acdcfae45 100644 --- a/libc/src/network/htons.h +++ b/libc/src/arpa/inet/htons.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_NETWORK_HTONS_H -#define LLVM_LIBC_SRC_NETWORK_HTONS_H +#ifndef LLVM_LIBC_SRC_ARPA_INET_HTONS_H +#define LLVM_LIBC_SRC_ARPA_INET_HTONS_H #include "src/__support/macros/config.h" #include @@ -18,4 +18,4 @@ uint16_t htons(uint16_t hostshort); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_NETWORK_HTONS_H +#endif // LLVM_LIBC_SRC_ARPA_INET_HTONS_H diff --git a/libc/src/network/ntohl.cpp b/libc/src/arpa/inet/ntohl.cpp similarity index 95% rename from libc/src/network/ntohl.cpp rename to libc/src/arpa/inet/ntohl.cpp index 6a309e97fca79..d472107a1988c 100644 --- a/libc/src/network/ntohl.cpp +++ b/libc/src/arpa/inet/ntohl.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/network/ntohl.h" +#include "src/arpa/inet/ntohl.h" #include "src/__support/common.h" #include "src/__support/endian_internal.h" #include "src/__support/macros/config.h" diff --git a/libc/src/network/ntohl.h b/libc/src/arpa/inet/ntohl.h similarity index 81% rename from libc/src/network/ntohl.h rename to libc/src/arpa/inet/ntohl.h index c325951948062..40079650d6fd1 100644 --- a/libc/src/network/ntohl.h +++ b/libc/src/arpa/inet/ntohl.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_NETWORK_NTOHL_H -#define LLVM_LIBC_SRC_NETWORK_NTOHL_H +#ifndef LLVM_LIBC_SRC_ARPA_INET_NTOHL_H +#define LLVM_LIBC_SRC_ARPA_INET_NTOHL_H #include "src/__support/macros/config.h" #include @@ -18,4 +18,4 @@ uint32_t ntohl(uint32_t netlong); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_NETWORK_NTOHL_H +#endif // LLVM_LIBC_SRC_ARPA_INET_NTOHL_H diff --git a/libc/src/network/ntohs.cpp b/libc/src/arpa/inet/ntohs.cpp similarity index 95% rename from libc/src/network/ntohs.cpp rename to libc/src/arpa/inet/ntohs.cpp index b51ecb93241ca..9082ed928778e 100644 --- a/libc/src/network/ntohs.cpp +++ b/libc/src/arpa/inet/ntohs.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/network/ntohs.h" +#include "src/arpa/inet/ntohs.h" #include "src/__support/common.h" #include "src/__support/endian_internal.h" #include "src/__support/macros/config.h" diff --git a/libc/src/network/ntohs.h b/libc/src/arpa/inet/ntohs.h similarity index 81% rename from libc/src/network/ntohs.h rename to libc/src/arpa/inet/ntohs.h index f55591415f764..5fe3ebcb62520 100644 --- a/libc/src/network/ntohs.h +++ b/libc/src/arpa/inet/ntohs.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_NETWORK_NTOHS_H -#define LLVM_LIBC_SRC_NETWORK_NTOHS_H +#ifndef LLVM_LIBC_SRC_ARPA_INET_NTOHS_H +#define LLVM_LIBC_SRC_ARPA_INET_NTOHS_H #include "src/__support/macros/config.h" #include @@ -18,4 +18,4 @@ uint16_t ntohs(uint16_t netshort); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_NETWORK_NTOHS_H +#endif // LLVM_LIBC_SRC_ARPA_INET_NTOHS_H diff --git a/libc/src/complex/CMakeLists.txt b/libc/src/complex/CMakeLists.txt index 289cce5455af7..7306e2fe925e3 100644 --- a/libc/src/complex/CMakeLists.txt +++ b/libc/src/complex/CMakeLists.txt @@ -24,3 +24,9 @@ add_complex_entrypoint_object(cimagf) add_complex_entrypoint_object(cimagl) add_complex_entrypoint_object(cimagf16) add_complex_entrypoint_object(cimagf128) + +add_complex_entrypoint_object(conj) +add_complex_entrypoint_object(conjf) +add_complex_entrypoint_object(conjl) +add_complex_entrypoint_object(conjf16) +add_complex_entrypoint_object(conjf128) diff --git a/libc/src/sys/mman/process_mrelease.h b/libc/src/complex/conj.h similarity index 53% rename from libc/src/sys/mman/process_mrelease.h rename to libc/src/complex/conj.h index 6c800f2d0eab8..2ff82d2758620 100644 --- a/libc/src/sys/mman/process_mrelease.h +++ b/libc/src/complex/conj.h @@ -1,21 +1,20 @@ -//===-- Implementation header for process_mrelease function -*- C++ -*-===// +//===-- Implementation header for conj --------------------------*- 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_SYS_MMAN_PROCESS_MRELEASE_H -#define LLVM_LIBC_SRC_SYS_MMAN_PROCESS_MRELEASE_H +#ifndef LLVM_LIBC_SRC_COMPLEX_CONJ_H +#define LLVM_LIBC_SRC_COMPLEX_CONJ_H #include "src/__support/macros/config.h" -#include // For size_t and off_t namespace LIBC_NAMESPACE_DECL { -int process_mrelease(int pidfd, unsigned int flags); +_Complex double conj(_Complex double x); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_SYS_MMAN_PROCESS_MRELEASE_H +#endif // LLVM_LIBC_SRC_COMPLEX_CONJ_H diff --git a/libc/src/complex/conjf.h b/libc/src/complex/conjf.h new file mode 100644 index 0000000000000..6b3bd612e5bf7 --- /dev/null +++ b/libc/src/complex/conjf.h @@ -0,0 +1,20 @@ +//===-- Implementation header for conjf -------------------------*- 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_COMPLEX_CONJF_H +#define LLVM_LIBC_SRC_COMPLEX_CONJF_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +_Complex float conjf(_Complex float x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_COMPLEX_CONJF_H diff --git a/libc/src/complex/conjf128.h b/libc/src/complex/conjf128.h new file mode 100644 index 0000000000000..587c979d315ef --- /dev/null +++ b/libc/src/complex/conjf128.h @@ -0,0 +1,27 @@ +//===-- Implementation header for conjf128 ----------------------*- 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/macros/properties/complex_types.h" +#include "src/__support/macros/properties/types.h" + +#if defined(LIBC_TYPES_HAS_CFLOAT128) + +#ifndef LLVM_LIBC_SRC_COMPLEX_CONJF128_H +#define LLVM_LIBC_SRC_COMPLEX_CONJF128_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +cfloat128 conjf128(cfloat128 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_COMPLEX_CONJF128_H + +#endif // LIBC_TYPES_HAS_CFLOAT128 diff --git a/libc/src/complex/conjf16.h b/libc/src/complex/conjf16.h new file mode 100644 index 0000000000000..b15c5b3f61f4a --- /dev/null +++ b/libc/src/complex/conjf16.h @@ -0,0 +1,27 @@ +//===-- Implementation header for conjf16 -----------------------*- 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/macros/properties/complex_types.h" +#include "src/__support/macros/properties/types.h" + +#if defined(LIBC_TYPES_HAS_CFLOAT16) + +#ifndef LLVM_LIBC_SRC_COMPLEX_CONJF16_H +#define LLVM_LIBC_SRC_COMPLEX_CONJF16_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +cfloat16 conjf16(cfloat16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_COMPLEX_CONJF16_H + +#endif // LIBC_TYPES_HAS_CFLOAT16 diff --git a/libc/src/complex/conjl.h b/libc/src/complex/conjl.h new file mode 100644 index 0000000000000..aec640f9433ac --- /dev/null +++ b/libc/src/complex/conjl.h @@ -0,0 +1,20 @@ +//===-- Implementation header for conjl -------------------------*- 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_COMPLEX_CONJL_H +#define LLVM_LIBC_SRC_COMPLEX_CONJL_H + +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +_Complex long double conjl(_Complex long double x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_COMPLEX_CONJL_H diff --git a/libc/src/complex/generic/CMakeLists.txt b/libc/src/complex/generic/CMakeLists.txt index a3da781c60237..cc14f89122edd 100644 --- a/libc/src/complex/generic/CMakeLists.txt +++ b/libc/src/complex/generic/CMakeLists.txt @@ -1,3 +1,72 @@ +add_entrypoint_object( + conj + SRCS + conj.cpp + HDRS + ../conj.h + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.__support.CPP.bit + libc.src.__support.complex_type +) + +add_entrypoint_object( + conjf + SRCS + conjf.cpp + HDRS + ../conjf.h + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.__support.CPP.bit + libc.src.__support.complex_type +) + +add_entrypoint_object( + conjl + SRCS + conjl.cpp + HDRS + ../conjl.h + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.__support.CPP.bit + libc.src.__support.complex_type +) + +add_entrypoint_object( + conjf16 + SRCS + conjf16.cpp + HDRS + ../conjf16.h + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.__support.CPP.bit + libc.src.__support.complex_type + libc.src.__support.macros.properties.types + libc.src.__support.macros.properties.complex_types +) + +add_entrypoint_object( + conjf128 + SRCS + conjf128.cpp + HDRS + ../conjf128.h + COMPILE_OPTIONS + ${libc_opt_high_flag} + DEPENDS + libc.src.__support.CPP.bit + libc.src.__support.complex_type + libc.src.__support.macros.properties.types + libc.src.__support.macros.properties.complex_types +) + add_entrypoint_object( creal SRCS diff --git a/libc/src/complex/generic/conj.cpp b/libc/src/complex/generic/conj.cpp new file mode 100644 index 0000000000000..1a93bc25dc3c4 --- /dev/null +++ b/libc/src/complex/generic/conj.cpp @@ -0,0 +1,20 @@ +//===-- Implementation of conj function -----------------------------------===// +// +// 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/complex/conj.h" +#include "src/__support/CPP/bit.h" +#include "src/__support/common.h" +#include "src/__support/complex_type.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(_Complex double, conj, (_Complex double x)) { + return conjugate<_Complex double>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/complex/generic/conjf.cpp b/libc/src/complex/generic/conjf.cpp new file mode 100644 index 0000000000000..33cb34340a04e --- /dev/null +++ b/libc/src/complex/generic/conjf.cpp @@ -0,0 +1,20 @@ +//===-- Implementation of conjf function ----------------------------------===// +// +// 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/complex/conjf.h" +#include "src/__support/CPP/bit.h" +#include "src/__support/common.h" +#include "src/__support/complex_type.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(_Complex float, conjf, (_Complex float x)) { + return conjugate<_Complex float>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/complex/generic/conjf128.cpp b/libc/src/complex/generic/conjf128.cpp new file mode 100644 index 0000000000000..4e35b3d5a97b7 --- /dev/null +++ b/libc/src/complex/generic/conjf128.cpp @@ -0,0 +1,24 @@ +//===-- Implementation of conjf128 function -------------------------------===// +// +// 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/complex/conjf128.h" +#if defined(LIBC_TYPES_HAS_CFLOAT128) + +#include "src/__support/CPP/bit.h" +#include "src/__support/common.h" +#include "src/__support/complex_type.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(cfloat128, conjf128, (cfloat128 x)) { + return conjugate(x); +} + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_CFLOAT128 diff --git a/libc/src/complex/generic/conjf16.cpp b/libc/src/complex/generic/conjf16.cpp new file mode 100644 index 0000000000000..2564fe252027a --- /dev/null +++ b/libc/src/complex/generic/conjf16.cpp @@ -0,0 +1,24 @@ +//===-- Implementation of conjf16 function --------------------------------===// +// +// 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/complex/conjf16.h" +#if defined(LIBC_TYPES_HAS_CFLOAT16) + +#include "src/__support/CPP/bit.h" +#include "src/__support/common.h" +#include "src/__support/complex_type.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(cfloat16, conjf16, (cfloat16 x)) { + return conjugate(x); +} + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LIBC_TYPES_HAS_CFLOAT16 diff --git a/libc/src/complex/generic/conjl.cpp b/libc/src/complex/generic/conjl.cpp new file mode 100644 index 0000000000000..dc071ab1ec51b --- /dev/null +++ b/libc/src/complex/generic/conjl.cpp @@ -0,0 +1,20 @@ +//===-- Implementation of conjl function ----------------------------------===// +// +// 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/complex/conjl.h" +#include "src/__support/CPP/bit.h" +#include "src/__support/common.h" +#include "src/__support/complex_type.h" + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(_Complex long double, conjl, (_Complex long double x)) { + return conjugate<_Complex long double>(x); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/CMakeLists.txt b/libc/src/math/CMakeLists.txt index 390a59d07a28b..e4e2c49642f2d 100644 --- a/libc/src/math/CMakeLists.txt +++ b/libc/src/math/CMakeLists.txt @@ -89,6 +89,7 @@ add_math_entrypoint_object(copysignf128) add_math_entrypoint_object(cos) add_math_entrypoint_object(cosf) +add_math_entrypoint_object(cosf16) add_math_entrypoint_object(cosh) add_math_entrypoint_object(coshf) diff --git a/libc/src/math/cosf16.h b/libc/src/math/cosf16.h new file mode 100644 index 0000000000000..cc179a6e16c62 --- /dev/null +++ b/libc/src/math/cosf16.h @@ -0,0 +1,21 @@ +//===-- Implementation header for cosf16 ------------------------*- 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_MATH_COSF16_H +#define LLVM_LIBC_SRC_MATH_COSF16_H + +#include "src/__support/macros/config.h" +#include "src/__support/macros/properties/types.h" + +namespace LIBC_NAMESPACE_DECL { + +float16 cosf16(float16 x); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_MATH_COSF16_H diff --git a/libc/src/math/generic/CMakeLists.txt b/libc/src/math/generic/CMakeLists.txt index aeb758d4a092d..b3d4612915197 100644 --- a/libc/src/math/generic/CMakeLists.txt +++ b/libc/src/math/generic/CMakeLists.txt @@ -418,6 +418,25 @@ add_entrypoint_object( ${libc_opt_high_flag} ) +add_entrypoint_object( + cosf16 + SRCS + cosf16.cpp + HDRS + ../cosf16.h + DEPENDS + .sincosf16_utils + libc.hdr.errno_macros + libc.hdr.fenv_macros + libc.src.__support.FPUtil.cast + libc.src.__support.FPUtil.fenv_impl + libc.src.__support.FPUtil.fp_bits + libc.src.__support.FPUtil.except_value_utils + libc.src.__support.FPUtil.multiply_add + libc.src.__support.macros.optimization + libc.src.__support.macros.properties.types +) + add_entrypoint_object( cospif SRCS diff --git a/libc/src/math/generic/cosf16.cpp b/libc/src/math/generic/cosf16.cpp new file mode 100644 index 0000000000000..534e07854474e --- /dev/null +++ b/libc/src/math/generic/cosf16.cpp @@ -0,0 +1,84 @@ +//===-- Half-precision cos(x) function ------------------------------------===// +// +// 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/math/cosf16.h" +#include "hdr/errno_macros.h" +#include "hdr/fenv_macros.h" +#include "sincosf16_utils.h" +#include "src/__support/FPUtil/FEnvImpl.h" +#include "src/__support/FPUtil/FPBits.h" +#include "src/__support/FPUtil/cast.h" +#include "src/__support/FPUtil/except_value_utils.h" +#include "src/__support/FPUtil/multiply_add.h" +#include "src/__support/macros/optimization.h" + +namespace LIBC_NAMESPACE_DECL { + +constexpr size_t N_EXCEPTS = 4; + +constexpr fputil::ExceptValues COSF16_EXCEPTS{{ + // (input, RZ output, RU offset, RD offset, RN offset) + {0x2b7c, 0x3bfc, 1, 0, 1}, + {0x4ac1, 0x38b5, 1, 0, 0}, + {0x5c49, 0xb8c6, 0, 1, 0}, + {0x7acc, 0xa474, 0, 1, 0}, +}}; + +LLVM_LIBC_FUNCTION(float16, cosf16, (float16 x)) { + using FPBits = fputil::FPBits; + FPBits xbits(x); + + uint16_t x_u = xbits.uintval(); + uint16_t x_abs = x_u & 0x7fff; + float xf = x; + + // Range reduction: + // For |x| > pi/32, we perform range reduction as follows: + // Find k and y such that: + // x = (k + y) * pi/32 + // k is an integer, |y| < 0.5 + // + // This is done by performing: + // k = round(x * 32/pi) + // y = x * 32/pi - k + // + // Once k and y are computed, we then deduce the answer by the cosine of sum + // formula: + // cos(x) = cos((k + y) * pi/32) + // = cos(k * pi/32) * cos(y * pi/32) - + // sin(k * pi/32) * sin(y * pi/32) + + // Handle exceptional values + if (auto r = COSF16_EXCEPTS.lookup(x_abs); LIBC_UNLIKELY(r.has_value())) + return r.value(); + + // cos(+/-0) = 1 + if (LIBC_UNLIKELY(x_abs == 0U)) + return fputil::cast(1.0f); + + // cos(+/-inf) = NaN, and cos(NaN) = NaN + if (xbits.is_inf_or_nan()) { + if (xbits.is_inf()) { + fputil::set_errno_if_required(EDOM); + fputil::raise_except_if_required(FE_INVALID); + } + + return x + FPBits::quiet_nan().get_val(); + } + + float sin_k, cos_k, sin_y, cosm1_y; + sincosf16_eval(xf, sin_k, cos_k, sin_y, cosm1_y); + // Since, cosm1_y = cos_y - 1, therefore: + // cos(x) = cos_k * cos_y - sin_k * sin_y + // = cos_k * (cos_y - 1 + 1) - sin_k * sin_y + // = cos_k * cosm1_y - sin_k * sin_y + cos_k + return fputil::cast(fputil::multiply_add( + cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k))); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/math/generic/cospif16.cpp b/libc/src/math/generic/cospif16.cpp index 384b39ff8e2c4..ee74bdb4a3693 100644 --- a/libc/src/math/generic/cospif16.cpp +++ b/libc/src/math/generic/cospif16.cpp @@ -73,7 +73,7 @@ LLVM_LIBC_FUNCTION(float16, cospif16, (float16 x)) { return fputil::cast(0.0f); // Since, cosm1_y = cos_y - 1, therefore: - // cos(x * pi) = cos_k(cosm1_y) + cos_k - sin_k * sin_y + // cos(x * pi) = cos_k(cosm1_y) + cos_k - sin_k * sin_y return fputil::cast(fputil::multiply_add( cos_k, cosm1_y, fputil::multiply_add(-sin_k, sin_y, cos_k))); } diff --git a/libc/src/math/generic/sinf16.cpp b/libc/src/math/generic/sinf16.cpp index 86546348ba739..7c15951cccecf 100644 --- a/libc/src/math/generic/sinf16.cpp +++ b/libc/src/math/generic/sinf16.cpp @@ -54,13 +54,10 @@ LLVM_LIBC_FUNCTION(float16, sinf16, (float16 x)) { // sin(y * pi/32) * cos(k * pi/32) // Handle exceptional values - if (LIBC_UNLIKELY(x_abs == 0x585c || x_abs == 0x5cb0 || x_abs == 0x51f5 || - x_abs == 0x2b45)) { - bool x_sign = x_u >> 15; - if (auto r = SINF16_EXCEPTS.lookup_odd(x_abs, x_sign); - LIBC_UNLIKELY(r.has_value())) - return r.value(); - } + bool x_sign = x_u >> 15; + if (auto r = SINF16_EXCEPTS.lookup_odd(x_abs, x_sign); + LIBC_UNLIKELY(r.has_value())) + return r.value(); int rounding = fputil::quick_get_round(); @@ -99,8 +96,8 @@ LLVM_LIBC_FUNCTION(float16, sinf16, (float16 x)) { if (LIBC_UNLIKELY(sin_y == 0 && sin_k == 0)) return FPBits::zero(xbits.sign()).get_val(); - // Since, cosm1_y = cos_y - 1, therfore: - // sin(x) = cos_k * sin_y + sin_k + (cosm1_y * sin_k) + // Since, cosm1_y = cos_y - 1, therefore: + // sin(x) = cos_k * sin_y + sin_k + (cosm1_y * sin_k) return fputil::cast(fputil::multiply_add( sin_y, cos_k, fputil::multiply_add(cosm1_y, sin_k, sin_k))); } diff --git a/libc/src/stdlib/CMakeLists.txt b/libc/src/stdlib/CMakeLists.txt index 14d06534a6049..40ba9ead9a7ae 100644 --- a/libc/src/stdlib/CMakeLists.txt +++ b/libc/src/stdlib/CMakeLists.txt @@ -323,7 +323,7 @@ add_entrypoint_object( .rand_util ) -if(NOT LIBC_TARGET_OS_IS_GPU) +if(NOT LIBC_TARGET_OS_IS_BAREMETAL AND NOT LIBC_TARGET_OS_IS_GPU) if(LLVM_LIBC_INCLUDE_SCUDO) set(SCUDO_DEPS "") @@ -349,7 +349,7 @@ if(NOT LIBC_TARGET_OS_IS_GPU) list(APPEND SCUDO_DEPS RTScudoStandalone.${LIBC_TARGET_ARCHITECTURE_FOR_SCUDO} RTScudoStandaloneCWrappers.${LIBC_TARGET_ARCHITECTURE_FOR_SCUDO}) - + if (COMPILER_RT_BUILD_GWP_ASAN) list(APPEND SCUDO_DEPS RTGwpAsan.${LIBC_TARGET_ARCHITECTURE_FOR_SCUDO} @@ -389,32 +389,8 @@ if(NOT LIBC_TARGET_OS_IS_GPU) ${SCUDO_DEPS} ) else() - # Only use freelist malloc for baremetal targets. - add_entrypoint_object( - freelist_malloc - SRCS - freelist_malloc.cpp - HDRS - malloc.h - DEPENDS - libc.src.__support.freelist_heap - ) - get_target_property(freelist_malloc_is_skipped libc.src.stdlib.freelist_malloc "SKIPPED") - if(LIBC_TARGET_OS_IS_BAREMETAL AND NOT freelist_malloc_is_skipped) - add_entrypoint_object( - malloc - ALIAS - DEPENDS - .freelist_malloc - ) - else() - add_entrypoint_external( - malloc - ) - endif() - add_entrypoint_external( - free + malloc ) add_entrypoint_external( calloc @@ -425,6 +401,12 @@ if(NOT LIBC_TARGET_OS_IS_GPU) add_entrypoint_external( aligned_alloc ) + add_entrypoint_external( + free + ) + add_entrypoint_external( + mallopt + ) endif() endif() @@ -513,7 +495,7 @@ if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}) endif() -if(LIBC_TARGET_OS_IS_GPU) +if(LIBC_TARGET_OS_IS_BAREMETAL OR LIBC_TARGET_OS_IS_GPU) add_entrypoint_object( malloc ALIAS diff --git a/libc/src/stdlib/baremetal/CMakeLists.txt b/libc/src/stdlib/baremetal/CMakeLists.txt index 551a83a36b20e..67ab1979e4d10 100644 --- a/libc/src/stdlib/baremetal/CMakeLists.txt +++ b/libc/src/stdlib/baremetal/CMakeLists.txt @@ -5,3 +5,53 @@ add_entrypoint_object( HDRS ../abort.h ) + +add_entrypoint_object( + malloc + SRCS + malloc.cpp + HDRS + ../malloc.h + DEPENDS + libc.src.__support.freelist_heap +) + +add_entrypoint_object( + free + SRCS + free.cpp + HDRS + ../free.h + DEPENDS + libc.src.__support.freelist_heap +) + +add_entrypoint_object( + calloc + SRCS + calloc.cpp + HDRS + ../calloc.h + DEPENDS + libc.src.__support.freelist_heap +) + +add_entrypoint_object( + realloc + SRCS + realloc.cpp + HDRS + ../realloc.h + DEPENDS + libc.src.__support.freelist_heap +) + +add_entrypoint_object( + aligned_alloc + SRCS + aligned_alloc.cpp + HDRS + ../aligned_alloc.h + DEPENDS + libc.src.__support.freelist_heap +) diff --git a/libc/src/stdlib/freelist_malloc.cpp b/libc/src/stdlib/baremetal/aligned_alloc.cpp similarity index 53% rename from libc/src/stdlib/freelist_malloc.cpp rename to libc/src/stdlib/baremetal/aligned_alloc.cpp index fe56fad769378..e9548719c3a63 100644 --- a/libc/src/stdlib/freelist_malloc.cpp +++ b/libc/src/stdlib/baremetal/aligned_alloc.cpp @@ -6,35 +6,14 @@ // //===----------------------------------------------------------------------===// +#include "src/stdlib/aligned_alloc.h" #include "src/__support/freelist_heap.h" #include "src/__support/macros/config.h" -#include "src/stdlib/aligned_alloc.h" -#include "src/stdlib/calloc.h" -#include "src/stdlib/free.h" -#include "src/stdlib/malloc.h" -#include "src/stdlib/realloc.h" #include namespace LIBC_NAMESPACE_DECL { -static LIBC_CONSTINIT FreeListHeap freelist_heap_symbols; -FreeListHeap *freelist_heap = &freelist_heap_symbols; - -LLVM_LIBC_FUNCTION(void *, malloc, (size_t size)) { - return freelist_heap->allocate(size); -} - -LLVM_LIBC_FUNCTION(void, free, (void *ptr)) { return freelist_heap->free(ptr); } - -LLVM_LIBC_FUNCTION(void *, calloc, (size_t num, size_t size)) { - return freelist_heap->calloc(num, size); -} - -LLVM_LIBC_FUNCTION(void *, realloc, (void *ptr, size_t size)) { - return freelist_heap->realloc(ptr, size); -} - LLVM_LIBC_FUNCTION(void *, aligned_alloc, (size_t alignment, size_t size)) { return freelist_heap->aligned_allocate(alignment, size); } diff --git a/libc/src/stdlib/baremetal/calloc.cpp b/libc/src/stdlib/baremetal/calloc.cpp new file mode 100644 index 0000000000000..2b3b83cebc8ac --- /dev/null +++ b/libc/src/stdlib/baremetal/calloc.cpp @@ -0,0 +1,21 @@ +//===-- Implementation for freelist_malloc --------------------------------===// +// +// 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/stdlib/calloc.h" +#include "src/__support/freelist_heap.h" +#include "src/__support/macros/config.h" + +#include + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(void *, calloc, (size_t num, size_t size)) { + return freelist_heap->calloc(num, size); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdlib/baremetal/free.cpp b/libc/src/stdlib/baremetal/free.cpp new file mode 100644 index 0000000000000..1e25fe5f2dcfe --- /dev/null +++ b/libc/src/stdlib/baremetal/free.cpp @@ -0,0 +1,19 @@ +//===-- Implementation for freelist_malloc --------------------------------===// +// +// 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/stdlib/free.h" +#include "src/__support/freelist_heap.h" +#include "src/__support/macros/config.h" + +#include + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(void, free, (void *ptr)) { return freelist_heap->free(ptr); } + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdlib/baremetal/malloc.cpp b/libc/src/stdlib/baremetal/malloc.cpp new file mode 100644 index 0000000000000..a299282667fcd --- /dev/null +++ b/libc/src/stdlib/baremetal/malloc.cpp @@ -0,0 +1,21 @@ +//===-- Implementation for freelist_malloc --------------------------------===// +// +// 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/stdlib/malloc.h" +#include "src/__support/freelist_heap.h" +#include "src/__support/macros/config.h" + +#include + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(void *, malloc, (size_t size)) { + return freelist_heap->allocate(size); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/stdlib/baremetal/realloc.cpp b/libc/src/stdlib/baremetal/realloc.cpp new file mode 100644 index 0000000000000..fb25c68ec4296 --- /dev/null +++ b/libc/src/stdlib/baremetal/realloc.cpp @@ -0,0 +1,21 @@ +//===-- Implementation for freelist_malloc --------------------------------===// +// +// 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/stdlib/realloc.h" +#include "src/__support/freelist_heap.h" +#include "src/__support/macros/config.h" + +#include + +namespace LIBC_NAMESPACE_DECL { + +LLVM_LIBC_FUNCTION(void *, realloc, (void *ptr, size_t size)) { + return freelist_heap->realloc(ptr, size); +} + +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/string/CMakeLists.txt b/libc/src/string/CMakeLists.txt index 8fe1226dd6a7a..e3faa543e630c 100644 --- a/libc/src/string/CMakeLists.txt +++ b/libc/src/string/CMakeLists.txt @@ -34,24 +34,6 @@ add_header_library( libc.src.__support.macros.config ) -add_entrypoint_object( - bcopy - SRCS - bcopy.cpp - HDRS - bcopy.h -) - -add_entrypoint_object( - index - SRCS - index.cpp - HDRS - index.h - DEPENDS - .string_utils -) - add_entrypoint_object( memccpy SRCS @@ -98,16 +80,6 @@ add_entrypoint_object( memrchr.h ) -add_entrypoint_object( - rindex - SRCS - rindex.cpp - HDRS - rindex.h - DEPENDS - .string_utils -) - add_entrypoint_object( stpcpy SRCS @@ -171,17 +143,6 @@ add_entrypoint_object( .memory_utils.inline_strcmp ) -add_entrypoint_object( - strcasecmp - SRCS - strcasecmp.cpp - HDRS - strcasecmp.h - DEPENDS - .memory_utils.inline_strcmp - libc.src.__support.ctype_utils -) - add_entrypoint_object( strcasestr SRCS @@ -319,17 +280,6 @@ add_entrypoint_object( .memory_utils.inline_strcmp ) -add_entrypoint_object( - strncasecmp - SRCS - strncasecmp.cpp - HDRS - strncasecmp.h - DEPENDS - .memory_utils.inline_strcmp - libc.src.__support.ctype_utils -) - add_entrypoint_object( strncpy SRCS @@ -475,102 +425,6 @@ add_entrypoint_object( .memory_utils.inline_memset ) -# Helper to define a function with multiple implementations -# - Computes flags to satisfy required/rejected features and arch, -# - Declares an entry point, -# - Attach the REQUIRE_CPU_FEATURES property to the target, -# - Add the fully qualified target to `${name}_implementations` global property for tests. -function(add_implementation name impl_name) - cmake_parse_arguments( - "ADD_IMPL" - "" # Optional arguments - "" # Single value arguments - "REQUIRE;SRCS;HDRS;DEPENDS;COMPILE_OPTIONS;MLLVM_COMPILE_OPTIONS" # Multi value arguments - ${ARGN}) - - if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") - # Note that '-mllvm' needs to be prefixed with 'SHELL:' to prevent CMake flag deduplication. - foreach(opt IN LISTS ADD_IMPL_MLLVM_COMPILE_OPTIONS) - list(APPEND ADD_IMPL_COMPILE_OPTIONS "SHELL:-mllvm ${opt}") - endforeach() - endif() - - if("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") - # Prevent warning when passing x86 SIMD types as template arguments. - # e.g. "warning: ignoring attributes on template argument ‘__m128i’ [-Wignored-attributes]" - list(APPEND ADD_IMPL_COMPILE_OPTIONS "-Wno-ignored-attributes") - endif() - - add_entrypoint_object(${impl_name} - NAME ${name} - SRCS ${ADD_IMPL_SRCS} - HDRS ${ADD_IMPL_HDRS} - DEPENDS ${ADD_IMPL_DEPENDS} - COMPILE_OPTIONS ${libc_opt_high_flag} ${ADD_IMPL_COMPILE_OPTIONS} - ) - get_fq_target_name(${impl_name} fq_target_name) - set_target_properties(${fq_target_name} PROPERTIES REQUIRE_CPU_FEATURES "${ADD_IMPL_REQUIRE}") - set_property(GLOBAL APPEND PROPERTY "${name}_implementations" "${fq_target_name}") -endfunction() - -# ------------------------------------------------------------------------------ -# bcmp -# ------------------------------------------------------------------------------ - -function(add_bcmp bcmp_name) - add_implementation(bcmp ${bcmp_name} - SRCS ${LIBC_SOURCE_DIR}/src/string/bcmp.cpp - HDRS ${LIBC_SOURCE_DIR}/src/string/bcmp.h - DEPENDS - .memory_utils.memory_utils - libc.include.string - ${ARGN} - ) -endfunction() - -if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) - add_bcmp(bcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) - add_bcmp(bcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) - add_bcmp(bcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) - add_bcmp(bcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512BW) - add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) - add_bcmp(bcmp) -elseif(LIBC_TARGET_OS_IS_GPU) - add_bcmp(bcmp) -else() - add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) - add_bcmp(bcmp) -endif() - -# ------------------------------------------------------------------------------ -# bzero -# ------------------------------------------------------------------------------ - -function(add_bzero bzero_name) - add_implementation(bzero ${bzero_name} - SRCS ${LIBC_SOURCE_DIR}/src/string/bzero.cpp - HDRS ${LIBC_SOURCE_DIR}/src/string/bzero.h - DEPENDS - .memory_utils.inline_memset - libc.include.string - ${ARGN} - ) -endfunction() - -if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) - add_bzero(bzero_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) - add_bzero(bzero_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) - add_bzero(bzero_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) - add_bzero(bzero_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) - add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) - add_bzero(bzero) -elseif(LIBC_TARGET_OS_IS_GPU) - add_bzero(bzero) -else() - add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) - add_bzero(bzero) -endif() - # ------------------------------------------------------------------------------ # memcmp # ------------------------------------------------------------------------------ diff --git a/libc/src/strings/CMakeLists.txt b/libc/src/strings/CMakeLists.txt new file mode 100644 index 0000000000000..5e84c7be1f7d6 --- /dev/null +++ b/libc/src/strings/CMakeLists.txt @@ -0,0 +1,97 @@ +function(add_bcmp bcmp_name) + add_implementation(bcmp ${bcmp_name} + SRCS ${LIBC_SOURCE_DIR}/src/strings/bcmp.cpp + HDRS ${LIBC_SOURCE_DIR}/src/strings/bcmp.h + DEPENDS + libc.src.string.memory_utils.memory_utils + ${ARGN} + ) +endfunction() + +if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) + add_bcmp(bcmp_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) + add_bcmp(bcmp_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) + add_bcmp(bcmp_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) + add_bcmp(bcmp_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512BW) + add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) + add_bcmp(bcmp) +elseif(LIBC_TARGET_OS_IS_GPU) + add_bcmp(bcmp) +else() + add_bcmp(bcmp_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) + add_bcmp(bcmp) +endif() + +function(add_bzero bzero_name) + add_implementation(bzero ${bzero_name} + SRCS ${LIBC_SOURCE_DIR}/src/strings/bzero.cpp + HDRS ${LIBC_SOURCE_DIR}/src/strings/bzero.h + DEPENDS + libc.src.string.memory_utils.inline_memset + ${ARGN} + ) +endfunction() + +if(${LIBC_TARGET_ARCHITECTURE_IS_X86}) + add_bzero(bzero_x86_64_opt_sse2 COMPILE_OPTIONS -march=k8 REQUIRE SSE2) + add_bzero(bzero_x86_64_opt_sse4 COMPILE_OPTIONS -march=nehalem REQUIRE SSE4_2) + add_bzero(bzero_x86_64_opt_avx2 COMPILE_OPTIONS -march=haswell REQUIRE AVX2) + add_bzero(bzero_x86_64_opt_avx512 COMPILE_OPTIONS -march=skylake-avx512 REQUIRE AVX512F) + add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) + add_bzero(bzero) +elseif(LIBC_TARGET_OS_IS_GPU) + add_bzero(bzero) +else() + add_bzero(bzero_opt_host COMPILE_OPTIONS ${LIBC_COMPILE_OPTIONS_NATIVE}) + add_bzero(bzero) +endif() + +add_entrypoint_object( + bcopy + SRCS + bcopy.cpp + HDRS + bcopy.h +) + +add_entrypoint_object( + index + SRCS + index.cpp + HDRS + index.h + DEPENDS + libc.src.string.string_utils +) + +add_entrypoint_object( + rindex + SRCS + rindex.cpp + HDRS + rindex.h + DEPENDS + libc.src.string.string_utils +) + +add_entrypoint_object( + strcasecmp + SRCS + strcasecmp.cpp + HDRS + strcasecmp.h + DEPENDS + libc.src.__support.ctype_utils + libc.src.string.memory_utils.inline_strcmp +) + +add_entrypoint_object( + strncasecmp + SRCS + strncasecmp.cpp + HDRS + strncasecmp.h + DEPENDS + libc.src.__support.ctype_utils + libc.src.string.memory_utils.inline_strcmp +) diff --git a/libc/src/string/bcmp.cpp b/libc/src/strings/bcmp.cpp similarity index 95% rename from libc/src/string/bcmp.cpp rename to libc/src/strings/bcmp.cpp index 6e9c9ae3b7a3b..083f13d3f95d3 100644 --- a/libc/src/string/bcmp.cpp +++ b/libc/src/strings/bcmp.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/string/bcmp.h" +#include "src/strings/bcmp.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/string/memory_utils/inline_bcmp.h" diff --git a/libc/src/string/bcmp.h b/libc/src/strings/bcmp.h similarity index 83% rename from libc/src/string/bcmp.h rename to libc/src/strings/bcmp.h index a82b529164d95..46b4d7163b52e 100644 --- a/libc/src/string/bcmp.h +++ b/libc/src/strings/bcmp.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_STRING_BCMP_H -#define LLVM_LIBC_SRC_STRING_BCMP_H +#ifndef LLVM_LIBC_SRC_STRINGS_BCMP_H +#define LLVM_LIBC_SRC_STRINGS_BCMP_H #include "src/__support/macros/config.h" #include // size_t @@ -18,4 +18,4 @@ int bcmp(const void *lhs, const void *rhs, size_t count); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_STRING_BCMP_H +#endif // LLVM_LIBC_SRC_STRINGS_BCMP_H diff --git a/libc/src/string/bcopy.cpp b/libc/src/strings/bcopy.cpp similarity index 95% rename from libc/src/string/bcopy.cpp rename to libc/src/strings/bcopy.cpp index 89aad71e354c7..eb0358c187472 100644 --- a/libc/src/string/bcopy.cpp +++ b/libc/src/strings/bcopy.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/string/bcopy.h" +#include "src/strings/bcopy.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/string/memory_utils/inline_memmove.h" diff --git a/libc/src/string/bcopy.h b/libc/src/strings/bcopy.h similarity index 83% rename from libc/src/string/bcopy.h rename to libc/src/strings/bcopy.h index 4cf0263a7d639..d8ee77e83c6d8 100644 --- a/libc/src/string/bcopy.h +++ b/libc/src/strings/bcopy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_STRING_BCOPY_H -#define LLVM_LIBC_SRC_STRING_BCOPY_H +#ifndef LLVM_LIBC_SRC_STRINGS_BCOPY_H +#define LLVM_LIBC_SRC_STRINGS_BCOPY_H #include "src/__support/macros/config.h" #include // size_t @@ -18,4 +18,4 @@ void bcopy(const void *src, void *dest, size_t count); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_STRING_BCOPY_H +#endif // LLVM_LIBC_SRC_STRINGS_BCOPY_H diff --git a/libc/src/string/bzero.cpp b/libc/src/strings/bzero.cpp similarity index 95% rename from libc/src/string/bzero.cpp rename to libc/src/strings/bzero.cpp index 7bcbee3547b9b..9c2e9700442af 100644 --- a/libc/src/string/bzero.cpp +++ b/libc/src/strings/bzero.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/string/bzero.h" +#include "src/strings/bzero.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" #include "src/string/memory_utils/inline_bzero.h" diff --git a/libc/src/string/bzero.h b/libc/src/strings/bzero.h similarity index 82% rename from libc/src/string/bzero.h rename to libc/src/strings/bzero.h index d9722197e8e8b..3e270fe41f6cd 100644 --- a/libc/src/string/bzero.h +++ b/libc/src/strings/bzero.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_STRING_BZERO_H -#define LLVM_LIBC_SRC_STRING_BZERO_H +#ifndef LLVM_LIBC_SRC_STRINGS_BZERO_H +#define LLVM_LIBC_SRC_STRINGS_BZERO_H #include "src/__support/macros/config.h" #include // size_t @@ -18,4 +18,4 @@ void bzero(void *ptr, size_t count); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_STRING_BZERO_H +#endif // LLVM_LIBC_SRC_STRINGS_BZERO_H diff --git a/libc/src/string/index.cpp b/libc/src/strings/index.cpp similarity index 95% rename from libc/src/string/index.cpp rename to libc/src/strings/index.cpp index 46cf54825f6ce..33b2be9f33e0d 100644 --- a/libc/src/string/index.cpp +++ b/libc/src/strings/index.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/string/index.h" +#include "src/strings/index.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" diff --git a/libc/src/string/index.h b/libc/src/strings/index.h similarity index 81% rename from libc/src/string/index.h rename to libc/src/strings/index.h index 9843bcdf9a573..d382cdd249aa9 100644 --- a/libc/src/string/index.h +++ b/libc/src/strings/index.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_STRING_INDEX_H -#define LLVM_LIBC_SRC_STRING_INDEX_H +#ifndef LLVM_LIBC_SRC_STRINGS_INDEX_H +#define LLVM_LIBC_SRC_STRINGS_INDEX_H #include "src/__support/macros/config.h" @@ -17,4 +17,4 @@ char *index(const char *src, int c); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_STRING_INDEX_H +#endif // LLVM_LIBC_SRC_STRINGS_INDEX_H diff --git a/libc/src/string/rindex.cpp b/libc/src/strings/rindex.cpp similarity index 95% rename from libc/src/string/rindex.cpp rename to libc/src/strings/rindex.cpp index 25879ddb07f62..1242e0faf85fc 100644 --- a/libc/src/string/rindex.cpp +++ b/libc/src/strings/rindex.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/string/rindex.h" +#include "src/strings/rindex.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" diff --git a/libc/src/string/rindex.h b/libc/src/strings/rindex.h similarity index 81% rename from libc/src/string/rindex.h rename to libc/src/strings/rindex.h index cfc35daa1f4d5..f8aa7b9be28f5 100644 --- a/libc/src/string/rindex.h +++ b/libc/src/strings/rindex.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_STRING_RINDEX_H -#define LLVM_LIBC_SRC_STRING_RINDEX_H +#ifndef LLVM_LIBC_SRC_STRINGS_RINDEX_H +#define LLVM_LIBC_SRC_STRINGS_RINDEX_H #include "src/__support/macros/config.h" @@ -17,4 +17,4 @@ char *rindex(const char *src, int c); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_STRING_RINDEX_H +#endif // LLVM_LIBC_SRC_STRINGS_RINDEX_H diff --git a/libc/src/string/strcasecmp.cpp b/libc/src/strings/strcasecmp.cpp similarity index 96% rename from libc/src/string/strcasecmp.cpp rename to libc/src/strings/strcasecmp.cpp index 1274c047fc28e..4bbe2909df1e2 100644 --- a/libc/src/string/strcasecmp.cpp +++ b/libc/src/strings/strcasecmp.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/string/strcasecmp.h" +#include "src/strings/strcasecmp.h" #include "src/__support/common.h" #include "src/__support/ctype_utils.h" diff --git a/libc/src/string/strcasecmp.h b/libc/src/strings/strcasecmp.h similarity index 80% rename from libc/src/string/strcasecmp.h rename to libc/src/strings/strcasecmp.h index 2916b8d417075..b02fb31615879 100644 --- a/libc/src/string/strcasecmp.h +++ b/libc/src/strings/strcasecmp.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_STRING_STRCASECMP_H -#define LLVM_LIBC_SRC_STRING_STRCASECMP_H +#ifndef LLVM_LIBC_SRC_STRINGS_STRCASECMP_H +#define LLVM_LIBC_SRC_STRINGS_STRCASECMP_H #include "src/__support/macros/config.h" @@ -17,4 +17,4 @@ int strcasecmp(const char *left, const char *right); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_STRING_STRCASECMP_H +#endif // LLVM_LIBC_SRC_STRINGS_STRCASECMP_H diff --git a/libc/src/string/strncasecmp.cpp b/libc/src/strings/strncasecmp.cpp similarity index 96% rename from libc/src/string/strncasecmp.cpp rename to libc/src/strings/strncasecmp.cpp index 45f82c98069b2..9c2f0ab131269 100644 --- a/libc/src/string/strncasecmp.cpp +++ b/libc/src/strings/strncasecmp.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/string/strncasecmp.h" +#include "src/strings/strncasecmp.h" #include "src/__support/common.h" #include "src/__support/ctype_utils.h" diff --git a/libc/src/string/strncasecmp.h b/libc/src/strings/strncasecmp.h similarity index 80% rename from libc/src/string/strncasecmp.h rename to libc/src/strings/strncasecmp.h index 15f74994ca56d..59df517058910 100644 --- a/libc/src/string/strncasecmp.h +++ b/libc/src/strings/strncasecmp.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_LIBC_SRC_STRING_STRNCASECMP_H -#define LLVM_LIBC_SRC_STRING_STRNCASECMP_H +#ifndef LLVM_LIBC_SRC_STRINGS_STRNCASECMP_H +#define LLVM_LIBC_SRC_STRINGS_STRNCASECMP_H #include "src/__support/macros/config.h" #include @@ -18,4 +18,4 @@ int strncasecmp(const char *left, const char *right, size_t n); } // namespace LIBC_NAMESPACE_DECL -#endif // LLVM_LIBC_SRC_STRING_STRNCASECMP_H +#endif // LLVM_LIBC_SRC_STRINGS_STRNCASECMP_H diff --git a/libc/src/sys/mman/CMakeLists.txt b/libc/src/sys/mman/CMakeLists.txt index 281efc0ffcdf2..4d4c2ad376050 100644 --- a/libc/src/sys/mman/CMakeLists.txt +++ b/libc/src/sys/mman/CMakeLists.txt @@ -113,9 +113,3 @@ add_entrypoint_object( DEPENDS .${LIBC_TARGET_OS}.mremap ) - -add_entrypoint_object( - process_mrelease - ALIAS - DEPENDS - .${LIBC_TARGET_OS}.process_mrelease) diff --git a/libc/src/sys/mman/linux/CMakeLists.txt b/libc/src/sys/mman/linux/CMakeLists.txt index aa2ca4b160181..89a0ad1527a06 100644 --- a/libc/src/sys/mman/linux/CMakeLists.txt +++ b/libc/src/sys/mman/linux/CMakeLists.txt @@ -36,6 +36,7 @@ add_entrypoint_object( libc.src.__support.OSUtil.osutil libc.src.errno.errno ) + add_entrypoint_object( munmap SRCS @@ -213,14 +214,3 @@ add_entrypoint_object( libc.src.unistd.unlink .shm_common ) - -add_entrypoint_object( - process_mrelease - SRCS - process_mrelease.cpp - HDRS - ../process_mrelease.h - DEPENDS - libc.include.sys_syscall - libc.src.__support.OSUtil.osutil - libc.src.errno.errno) diff --git a/libc/src/sys/mman/linux/process_mrelease.cpp b/libc/src/sys/mman/linux/process_mrelease.cpp deleted file mode 100644 index 7660f1e23ece2..0000000000000 --- a/libc/src/sys/mman/linux/process_mrelease.cpp +++ /dev/null @@ -1,41 +0,0 @@ -//===---------- Linux implementation of the mrelease function -----------===// -// -// 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/sys/mman/process_mrelease.h" - -#include "src/__support/OSUtil/syscall.h" // For internal syscall function. -#include "src/__support/common.h" - -#include "src/__support/macros/config.h" -#include "src/errno/libc_errno.h" -#include // For EXEC_PAGESIZE. -#include // For syscall numbers. - -namespace LIBC_NAMESPACE_DECL { - -LLVM_LIBC_FUNCTION(int, process_mrelease, (int pidfd, unsigned int flags)) { -#ifdef SYS_process_mrelease - long ret = - LIBC_NAMESPACE::syscall_impl(SYS_process_mrelease, pidfd, flags); - - if (ret < 0) { - libc_errno = static_cast(-ret); - return -1; - } - - return 0; -#else - // The system call is not available. - (void)pidfd; - (void)flags; - libc_errno = ENOSYS; - return -1; -#endif -} - -} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/time/CMakeLists.txt b/libc/src/time/CMakeLists.txt index f18e74a15e6fc..ae835dcc74274 100644 --- a/libc/src/time/CMakeLists.txt +++ b/libc/src/time/CMakeLists.txt @@ -106,9 +106,15 @@ add_entrypoint_object( add_entrypoint_object( time - ALIAS + SRCS + time.cpp + HDRS + time_func.h DEPENDS - .${LIBC_TARGET_OS}.time + libc.hdr.time_macros + libc.hdr.types.time_t + libc.src.__support.time.clock_gettime + libc.src.errno.errno ) add_entrypoint_object( @@ -145,3 +151,10 @@ add_entrypoint_object( DEPENDS .${LIBC_TARGET_OS}.gettimeofday ) + +add_entrypoint_object( + clock_getres + ALIAS + DEPENDS + .${LIBC_TARGET_OS}.clock_getres +) diff --git a/libc/src/time/clock_getres.h b/libc/src/time/clock_getres.h new file mode 100644 index 0000000000000..c1c581c535994 --- /dev/null +++ b/libc/src/time/clock_getres.h @@ -0,0 +1,21 @@ +//===-- Implementation header of clock_getres -------------------*- 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_TIME_CLOCK_GETRES_H +#define LLVM_LIBC_SRC_TIME_CLOCK_GETRES_H + +#include "hdr/types/clockid_t.h" +#include "hdr/types/struct_timespec.h" +#include "src/__support/macros/config.h" + +namespace LIBC_NAMESPACE_DECL { + +int clock_getres(clockid_t clockid, timespec *tp); + +} // namespace LIBC_NAMESPACE_DECL + +#endif // LLVM_LIBC_SRC_TIME_CLOCK_GETRES_H diff --git a/libc/src/time/gpu/CMakeLists.txt b/libc/src/time/gpu/CMakeLists.txt index 8da5d3a22f5a0..31a60595d68ff 100644 --- a/libc/src/time/gpu/CMakeLists.txt +++ b/libc/src/time/gpu/CMakeLists.txt @@ -1,14 +1,3 @@ -add_object_library( - time_utils - SRCS - time_utils.cpp - HDRS - time_utils.h - DEPENDS - libc.hdr.types.clock_t - libc.hdr.time_macros -) - add_entrypoint_object( clock SRCS @@ -18,7 +7,8 @@ add_entrypoint_object( DEPENDS libc.include.time libc.src.__support.GPU.utils - .time_utils + libc.src.__support.time.clock_gettime + libc.src.__support.time.gpu.time_utils ) add_entrypoint_object( @@ -30,29 +20,31 @@ add_entrypoint_object( DEPENDS libc.include.time libc.src.__support.GPU.utils - .time_utils + libc.src.__support.time.gpu.time_utils ) add_entrypoint_object( - clock_gettime + timespec_get SRCS - clock_gettime.cpp + timespec_get.cpp HDRS - ../clock_gettime.h + ../timespec_get.h DEPENDS - libc.hdr.types.clockid_t + libc.hdr.time_macros libc.hdr.types.struct_timespec - .time_utils + libc.src.__support.time.gpu.time_utils ) add_entrypoint_object( - timespec_get + clock_gettime SRCS - timespec_get.cpp + clock_gettime.cpp HDRS - ../timespec_get.h + ../clock_gettime.h DEPENDS libc.hdr.time_macros + libc.hdr.types.clockid_t libc.hdr.types.struct_timespec - .time_utils + libc.src.__support.time.gpu.time_utils + libc.src.__support.time.clock_gettime ) diff --git a/libc/src/time/gpu/clock.cpp b/libc/src/time/gpu/clock.cpp index 4cdb1d505aed2..add5b2725ef8f 100644 --- a/libc/src/time/gpu/clock.cpp +++ b/libc/src/time/gpu/clock.cpp @@ -8,7 +8,7 @@ #include "src/time/clock.h" #include "src/__support/macros/config.h" -#include "src/time/gpu/time_utils.h" +#include "src/__support/time/gpu/time_utils.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/time/gpu/clock_gettime.cpp b/libc/src/time/gpu/clock_gettime.cpp index de7899a2a17cc..81547ef7f1ca6 100644 --- a/libc/src/time/gpu/clock_gettime.cpp +++ b/libc/src/time/gpu/clock_gettime.cpp @@ -10,23 +10,16 @@ #include "src/__support/common.h" #include "src/__support/macros/config.h" -#include "time_utils.h" +#include "src/__support/time/clock_gettime.h" +#include "src/__support/time/gpu/time_utils.h" namespace LIBC_NAMESPACE_DECL { -constexpr uint64_t TICKS_PER_SEC = 1000000000UL; - LLVM_LIBC_FUNCTION(int, clock_gettime, (clockid_t clockid, timespec *ts)) { - if (clockid != CLOCK_MONOTONIC || !ts) - return -1; - - uint64_t ns_per_tick = TICKS_PER_SEC / GPU_CLOCKS_PER_SEC; - uint64_t ticks = gpu::fixed_frequency_clock(); - - ts->tv_nsec = (ticks * ns_per_tick) % TICKS_PER_SEC; - ts->tv_sec = (ticks * ns_per_tick) / TICKS_PER_SEC; - - return 0; + ErrorOr result = internal::clock_gettime(clockid, ts); + if (result) + return result.value(); + return result.error(); } } // namespace LIBC_NAMESPACE_DECL diff --git a/libc/src/time/gpu/nanosleep.cpp b/libc/src/time/gpu/nanosleep.cpp index 3f4a609dd40eb..25a22d5703fa7 100644 --- a/libc/src/time/gpu/nanosleep.cpp +++ b/libc/src/time/gpu/nanosleep.cpp @@ -9,7 +9,7 @@ #include "src/time/nanosleep.h" #include "src/__support/macros/config.h" -#include "time_utils.h" +#include "src/__support/time/gpu/time_utils.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/time/linux/CMakeLists.txt b/libc/src/time/linux/CMakeLists.txt index 31fd7d1e64c85..314623f9f425e 100644 --- a/libc/src/time/linux/CMakeLists.txt +++ b/libc/src/time/linux/CMakeLists.txt @@ -1,16 +1,3 @@ -add_entrypoint_object( - time - SRCS - time.cpp - HDRS - ../time_func.h - DEPENDS - libc.hdr.time_macros - libc.hdr.types.time_t - libc.src.__support.time.linux.clock_gettime - libc.src.errno.errno -) - add_entrypoint_object( timespec_get SRCS @@ -20,7 +7,7 @@ add_entrypoint_object( DEPENDS libc.hdr.time_macros libc.hdr.types.struct_timespec - libc.src.__support.time.linux.clock_gettime + libc.src.__support.time.clock_gettime libc.src.errno.errno ) @@ -34,7 +21,7 @@ add_entrypoint_object( libc.hdr.time_macros libc.hdr.types.clock_t libc.src.__support.time.units - libc.src.__support.time.linux.clock_gettime + libc.src.__support.time.clock_gettime libc.src.__support.CPP.limits libc.src.errno.errno ) @@ -62,7 +49,7 @@ add_entrypoint_object( DEPENDS libc.hdr.types.clockid_t libc.hdr.types.struct_timespec - libc.src.__support.time.linux.clock_gettime + libc.src.__support.time.clock_gettime libc.src.errno.errno ) @@ -75,7 +62,7 @@ add_entrypoint_object( DEPENDS libc.hdr.time_macros libc.hdr.types.suseconds_t - libc.src.__support.time.linux.clock_gettime + libc.src.__support.time.clock_gettime libc.src.__support.time.units libc.src.errno.errno ) diff --git a/libc/src/time/linux/clock.cpp b/libc/src/time/linux/clock.cpp index f43e1bcad6a3a..ee4fa82b4f894 100644 --- a/libc/src/time/linux/clock.cpp +++ b/libc/src/time/linux/clock.cpp @@ -11,7 +11,7 @@ #include "src/__support/CPP/limits.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" -#include "src/__support/time/linux/clock_gettime.h" +#include "src/__support/time/clock_gettime.h" #include "src/__support/time/units.h" #include "src/errno/libc_errno.h" diff --git a/libc/src/time/linux/clock_gettime.cpp b/libc/src/time/linux/clock_gettime.cpp index a2b20a6dbc987..743c644d65d02 100644 --- a/libc/src/time/linux/clock_gettime.cpp +++ b/libc/src/time/linux/clock_gettime.cpp @@ -9,7 +9,7 @@ #include "src/time/clock_gettime.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" -#include "src/__support/time/linux/clock_gettime.h" +#include "src/__support/time/clock_gettime.h" #include "src/errno/libc_errno.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/time/linux/gettimeofday.cpp b/libc/src/time/linux/gettimeofday.cpp index 19d9988ae73a6..e8ddf482fc984 100644 --- a/libc/src/time/linux/gettimeofday.cpp +++ b/libc/src/time/linux/gettimeofday.cpp @@ -11,7 +11,7 @@ #include "hdr/types/suseconds_t.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" -#include "src/__support/time/linux/clock_gettime.h" +#include "src/__support/time/clock_gettime.h" #include "src/__support/time/units.h" #include "src/errno/libc_errno.h" diff --git a/libc/src/time/linux/timespec_get.cpp b/libc/src/time/linux/timespec_get.cpp index ba9f8eb2e4426..cf5174523aa4f 100644 --- a/libc/src/time/linux/timespec_get.cpp +++ b/libc/src/time/linux/timespec_get.cpp @@ -10,7 +10,7 @@ #include "hdr/time_macros.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" -#include "src/__support/time/linux/clock_gettime.h" +#include "src/__support/time/clock_gettime.h" #include "src/errno/libc_errno.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/src/time/linux/time.cpp b/libc/src/time/time.cpp similarity index 83% rename from libc/src/time/linux/time.cpp rename to libc/src/time/time.cpp index 20fb86e8e29db..4a0b614a68ef5 100644 --- a/libc/src/time/linux/time.cpp +++ b/libc/src/time/time.cpp @@ -9,14 +9,14 @@ #include "hdr/time_macros.h" #include "src/__support/common.h" #include "src/__support/macros/config.h" -#include "src/__support/time/linux/clock_gettime.h" +#include "src/__support/time/clock_gettime.h" #include "src/errno/libc_errno.h" #include "src/time/time_func.h" namespace LIBC_NAMESPACE_DECL { - -LLVM_LIBC_FUNCTION(time_t, time, (time_t * tp)) { - // TODO: Use the Linux VDSO to fetch the time and avoid the syscall. +// avoid inconsitent clang-format behavior +using time_ptr_t = time_t *; +LLVM_LIBC_FUNCTION(time_t, time, (time_ptr_t tp)) { struct timespec ts; auto result = internal::clock_gettime(CLOCK_REALTIME, &ts); if (!result.has_value()) { diff --git a/libc/src/time/windows/CMakeLists.txt b/libc/src/time/windows/CMakeLists.txt new file mode 100644 index 0000000000000..6f242cd168f52 --- /dev/null +++ b/libc/src/time/windows/CMakeLists.txt @@ -0,0 +1,13 @@ +add_entrypoint_object( + clock_getres + SRCS + clock_getres.cpp + DEPENDS + libc.src.__support.time.windows.performance_counter + libc.src.__support.time.units + libc.src.__support.common + libc.src.__support.macros.optimization + libc.hdr.time_macros + libc.hdr.types.time_t + libc.hdr.types.struct_timespec +) diff --git a/libc/src/time/windows/clock_getres.cpp b/libc/src/time/windows/clock_getres.cpp new file mode 100644 index 0000000000000..b8c0c82aa6419 --- /dev/null +++ b/libc/src/time/windows/clock_getres.cpp @@ -0,0 +1,110 @@ +//===-- Windows implementation of clock_getres ------------------*- 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 "hdr/errno_macros.h" +#include "hdr/time_macros.h" +#include "hdr/types/clockid_t.h" +#include "hdr/types/struct_timespec.h" + +#include "src/__support/CPP/limits.h" +#include "src/__support/common.h" +#include "src/__support/macros/optimization.h" +#include "src/__support/time/units.h" +#include "src/__support/time/windows/performance_counter.h" +#include "src/errno/libc_errno.h" +#include "src/time/clock_getres.h" + +#define WIN32_LEAN_AND_MEAN +#define NOMINMAX +#include + +// add in dependencies for GetSystemTimeAdjustmentPrecise +#pragma comment(lib, "mincore.lib") + +namespace LIBC_NAMESPACE_DECL { +LLVM_LIBC_FUNCTION(int, clock_getres, (clockid_t id, struct timespec *res)) { + using namespace time_units; + // POSIX allows nullptr to be passed as res, in which case the function should + // do nothing. + if (res == nullptr) + return 0; + constexpr unsigned long long HNS_PER_SEC = 1_s_ns / 100ULL; + constexpr unsigned long long SEC_LIMIT = + cpp::numeric_limitstv_sec)>::max(); + // For CLOCK_MONOTONIC, we are using performance counter + // https://learn.microsoft.com/en-us/windows/win32/sysinfo/acquiring-high-resolution-time-stamps + // Hence, the resolution is given by the performance counter frequency. + // For CLOCK_REALTIME, the precision is given by + // GetSystemTimeAdjustmentPrecise + // (https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeadjustmentprecise) + // For CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID, the precision is + // given by GetSystemTimeAdjustment + // (https://learn.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeadjustment) + switch (id) { + default: + libc_errno = EINVAL; + return -1; + + case CLOCK_MONOTONIC: { + long long freq = performance_counter::get_ticks_per_second(); + __builtin_assume(freq != 0); + // division of 1 second by frequency, rounded up. + long long tv_sec = static_cast(freq == 1); + long long tv_nsec = + LIBC_LIKELY(freq != 1) ? 1ll + ((1_s_ns - 1ll) / freq) : 0ll; + // not possible to overflow tv_sec, tv_nsec + res->tv_sec = static_casttv_sec)>(tv_sec); + res->tv_nsec = static_casttv_nsec)>(tv_nsec); + break; + } + + case CLOCK_REALTIME: { + [[clang::uninitialized]] DWORD64 time_adjustment; + [[clang::uninitialized]] DWORD64 time_increment; + [[clang::uninitialized]] BOOL time_adjustment_disabled; + if (!::GetSystemTimeAdjustmentPrecise(&time_adjustment, &time_increment, + &time_adjustment_disabled)) { + libc_errno = EINVAL; + return -1; + } + DWORD64 tv_sec = time_increment / HNS_PER_SEC; + DWORD64 tv_nsec = (time_increment % HNS_PER_SEC) * 100ULL; + if (LIBC_UNLIKELY(tv_sec > SEC_LIMIT)) { + libc_errno = EOVERFLOW; + return -1; + } + res->tv_sec = static_casttv_sec)>(tv_sec); + res->tv_nsec = static_casttv_nsec)>(tv_nsec); + break; + } + case CLOCK_PROCESS_CPUTIME_ID: + case CLOCK_THREAD_CPUTIME_ID: { + [[clang::uninitialized]] DWORD time_adjustment; + [[clang::uninitialized]] DWORD time_increment; + [[clang::uninitialized]] BOOL time_adjustment_disabled; + if (!::GetSystemTimeAdjustment(&time_adjustment, &time_increment, + &time_adjustment_disabled)) { + libc_errno = EINVAL; + return -1; + } + DWORD hns_per_sec = static_cast(HNS_PER_SEC); + DWORD sec_limit = static_cast(SEC_LIMIT); + DWORD tv_sec = time_increment / hns_per_sec; + DWORD tv_nsec = (time_increment % hns_per_sec) * 100UL; + if (LIBC_UNLIKELY(tv_sec > sec_limit)) { + libc_errno = EOVERFLOW; + return -1; + } + res->tv_sec = static_casttv_sec)>(tv_sec); + res->tv_nsec = static_casttv_nsec)>(tv_nsec); + break; + } + } + return 0; +} +} // namespace LIBC_NAMESPACE_DECL diff --git a/libc/test/src/CMakeLists.txt b/libc/test/src/CMakeLists.txt index 8ac8f91e98d4c..31008508d6492 100644 --- a/libc/test/src/CMakeLists.txt +++ b/libc/test/src/CMakeLists.txt @@ -58,7 +58,9 @@ add_subdirectory(stdfix) add_subdirectory(stdio) add_subdirectory(stdlib) add_subdirectory(string) +add_subdirectory(strings) add_subdirectory(wchar) +add_subdirectory(time) # Depends on utilities in stdlib add_subdirectory(inttypes) @@ -75,15 +77,14 @@ if(NOT LLVM_LIBC_FULL_BUILD) return() endif() +add_subdirectory(arpa) add_subdirectory(assert) add_subdirectory(compiler) add_subdirectory(dirent) -add_subdirectory(network) +add_subdirectory(locale) add_subdirectory(setjmp) add_subdirectory(signal) add_subdirectory(spawn) -add_subdirectory(time) -add_subdirectory(locale) if(${LIBC_TARGET_OS} STREQUAL "linux") add_subdirectory(pthread) diff --git a/libc/test/src/__support/CMakeLists.txt b/libc/test/src/__support/CMakeLists.txt index bcc86effd9a52..aeb8edf305d05 100644 --- a/libc/test/src/__support/CMakeLists.txt +++ b/libc/test/src/__support/CMakeLists.txt @@ -55,7 +55,9 @@ if(NOT LIBC_TARGET_OS_IS_GPU) ) endif() -if(LLVM_LIBC_FULL_BUILD) +# TODO: FreeListHeap uses the _end symbol which conflicts with the _end symbol +# defined by GPU start.cpp files so for now we exclude this test on GPU. +if(LLVM_LIBC_FULL_BUILD AND NOT LIBC_TARGET_OS_IS_GPU) add_libc_test( freelist_heap_test SUITE @@ -63,11 +65,9 @@ if(LLVM_LIBC_FULL_BUILD) SRCS fake_heap.s freelist_heap_test.cpp - freelist_malloc_test.cpp DEPENDS libc.src.__support.CPP.span libc.src.__support.freelist_heap - libc.src.stdlib.freelist_malloc libc.src.string.memcmp libc.src.string.memcpy ) diff --git a/libc/test/src/__support/CPP/atomic_test.cpp b/libc/test/src/__support/CPP/atomic_test.cpp index 5b105c8eb3d56..5c3f60e9a68cd 100644 --- a/libc/test/src/__support/CPP/atomic_test.cpp +++ b/libc/test/src/__support/CPP/atomic_test.cpp @@ -32,3 +32,21 @@ TEST(LlvmLibcAtomicTest, CompareExchangeStrong) { ASSERT_FALSE(aint.compare_exchange_strong(desired, 100)); ASSERT_EQ(aint.load(LIBC_NAMESPACE::cpp::MemoryOrder::RELAXED), 100); } + +struct alignas(void *) TrivialData { + char a; + char b; + char padding[sizeof(void *) - 2]; +}; + +TEST(LlvmLibcAtomicTest, TrivialCompositeData) { + LIBC_NAMESPACE::cpp::Atomic data({'a', 'b', {}}); + ASSERT_EQ(data.load(LIBC_NAMESPACE::cpp::MemoryOrder::RELAXED).a, 'a'); + ASSERT_EQ(data.load(LIBC_NAMESPACE::cpp::MemoryOrder::RELAXED).b, 'b'); + + auto old = data.exchange({'c', 'd', {}}); + ASSERT_EQ(data.load(LIBC_NAMESPACE::cpp::MemoryOrder::RELAXED).a, 'c'); + ASSERT_EQ(data.load(LIBC_NAMESPACE::cpp::MemoryOrder::RELAXED).b, 'd'); + ASSERT_EQ(old.a, 'a'); + ASSERT_EQ(old.b, 'b'); +} diff --git a/libc/test/src/__support/CPP/type_traits_test.cpp b/libc/test/src/__support/CPP/type_traits_test.cpp index fa5298a12d3fc..4b3e48c6a6c0f 100644 --- a/libc/test/src/__support/CPP/type_traits_test.cpp +++ b/libc/test/src/__support/CPP/type_traits_test.cpp @@ -439,6 +439,28 @@ TEST(LlvmLibcTypeTraitsTest, is_object) { TEST(LlvmLibcTypeTraitsTest, true_type) { EXPECT_TRUE((true_type::value)); } +struct CompilerLeadingPadded { + char b; + int a; +}; + +struct CompilerTrailingPadded { + int a; + char b; +}; + +struct alignas(long long) ManuallyPadded { + int b; + char padding[sizeof(long long) - sizeof(int)]; +}; + +TEST(LlvmLibcTypeTraitsTest, has_unique_object_representations) { + EXPECT_TRUE(has_unique_object_representations::value); + EXPECT_FALSE(has_unique_object_representations_v); + EXPECT_FALSE(has_unique_object_representations_v); + EXPECT_TRUE(has_unique_object_representations_v); +} + // TODO type_identity // TODO void_t diff --git a/libc/test/src/__support/freelist_malloc_test.cpp b/libc/test/src/__support/freelist_malloc_test.cpp deleted file mode 100644 index 793e2498304fb..0000000000000 --- a/libc/test/src/__support/freelist_malloc_test.cpp +++ /dev/null @@ -1,54 +0,0 @@ -//===-- Unittests for freelist_malloc -------------------------------------===// -// -// 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/freelist_heap.h" -#include "src/stdlib/aligned_alloc.h" -#include "src/stdlib/calloc.h" -#include "src/stdlib/free.h" -#include "src/stdlib/malloc.h" -#include "test/UnitTest/Test.h" - -using LIBC_NAMESPACE::Block; -using LIBC_NAMESPACE::freelist_heap; -using LIBC_NAMESPACE::FreeListHeap; -using LIBC_NAMESPACE::FreeListHeapBuffer; - -TEST(LlvmLibcFreeListMalloc, Malloc) { - constexpr size_t kAllocSize = 256; - constexpr size_t kCallocNum = 4; - constexpr size_t kCallocSize = 64; - - void *ptr1 = LIBC_NAMESPACE::malloc(kAllocSize); - auto *block = Block::from_usable_space(ptr1); - EXPECT_GE(block->inner_size(), kAllocSize); - - LIBC_NAMESPACE::free(ptr1); - ASSERT_NE(block->next(), static_cast(nullptr)); - ASSERT_EQ(block->next()->next(), static_cast(nullptr)); - size_t heap_size = block->inner_size(); - - void *ptr2 = LIBC_NAMESPACE::calloc(kCallocNum, kCallocSize); - ASSERT_EQ(ptr2, ptr1); - EXPECT_GE(block->inner_size(), kCallocNum * kCallocSize); - - for (size_t i = 0; i < kCallocNum * kCallocSize; ++i) - EXPECT_EQ(reinterpret_cast(ptr2)[i], uint8_t(0)); - - LIBC_NAMESPACE::free(ptr2); - EXPECT_EQ(block->inner_size(), heap_size); - - constexpr size_t ALIGN = kAllocSize; - void *ptr3 = LIBC_NAMESPACE::aligned_alloc(ALIGN, kAllocSize); - EXPECT_NE(ptr3, static_cast(nullptr)); - EXPECT_EQ(reinterpret_cast(ptr3) % ALIGN, size_t(0)); - auto *aligned_block = reinterpret_cast(ptr3); - EXPECT_GE(aligned_block->inner_size(), kAllocSize); - - LIBC_NAMESPACE::free(ptr3); - EXPECT_EQ(block->inner_size(), heap_size); -} diff --git a/libc/test/src/__support/threads/linux/raw_mutex_test.cpp b/libc/test/src/__support/threads/linux/raw_mutex_test.cpp index 918f5d35c94f4..dadc706421d06 100644 --- a/libc/test/src/__support/threads/linux/raw_mutex_test.cpp +++ b/libc/test/src/__support/threads/linux/raw_mutex_test.cpp @@ -12,7 +12,7 @@ #include "src/__support/OSUtil/syscall.h" #include "src/__support/threads/linux/raw_mutex.h" #include "src/__support/threads/sleep.h" -#include "src/__support/time/linux/clock_gettime.h" +#include "src/__support/time/clock_gettime.h" #include "src/stdlib/exit.h" #include "src/sys/mman/mmap.h" #include "src/sys/mman/munmap.h" diff --git a/libc/test/src/arpa/CMakeLists.txt b/libc/test/src/arpa/CMakeLists.txt new file mode 100644 index 0000000000000..5c89828860ff8 --- /dev/null +++ b/libc/test/src/arpa/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(inet) diff --git a/libc/test/src/arpa/inet/CMakeLists.txt b/libc/test/src/arpa/inet/CMakeLists.txt new file mode 100644 index 0000000000000..6e78e3a50e612 --- /dev/null +++ b/libc/test/src/arpa/inet/CMakeLists.txt @@ -0,0 +1,53 @@ +add_custom_target(libc_arpa_inet_unittests) + +add_libc_unittest( + htonl + SUITE + libc_arpa_inet_unittests + SRCS + htonl_test.cpp + CXX_STANDARD + 20 + DEPENDS + libc.src.arpa.inet.htonl + libc.src.arpa.inet.ntohl +) + +add_libc_unittest( + htons + SUITE + libc_arpa_inet_unittests + SRCS + htons_test.cpp + CXX_STANDARD + 20 + DEPENDS + libc.src.arpa.inet.htons + libc.src.arpa.inet.ntohs +) + +add_libc_unittest( + ntohl + SUITE + libc_arpa_inet_unittests + SRCS + ntohl_test.cpp + CXX_STANDARD + 20 + DEPENDS + libc.src.arpa.inet.htonl + libc.src.arpa.inet.ntohl +) + +add_libc_unittest( + ntohs + SUITE + libc_arpa_inet_unittests + SRCS + ntohs_test.cpp + CXX_STANDARD + 20 + DEPENDS + libc.src.arpa.inet.htons + libc.src.arpa.inet.ntohs +) diff --git a/libc/test/src/network/htonl_test.cpp b/libc/test/src/arpa/inet/htonl_test.cpp similarity index 93% rename from libc/test/src/network/htonl_test.cpp rename to libc/test/src/arpa/inet/htonl_test.cpp index f2e2541312c31..4cc1e4cb4e886 100644 --- a/libc/test/src/network/htonl_test.cpp +++ b/libc/test/src/arpa/inet/htonl_test.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "src/__support/endian_internal.h" -#include "src/network/htonl.h" -#include "src/network/ntohl.h" +#include "src/arpa/inet/htonl.h" +#include "src/arpa/inet/ntohl.h" #include "test/UnitTest/Test.h" TEST(LlvmLibcHtonl, SmokeTest) { diff --git a/libc/test/src/network/htons_test.cpp b/libc/test/src/arpa/inet/htons_test.cpp similarity index 93% rename from libc/test/src/network/htons_test.cpp rename to libc/test/src/arpa/inet/htons_test.cpp index 9668162523ce5..6a95ec5587e95 100644 --- a/libc/test/src/network/htons_test.cpp +++ b/libc/test/src/arpa/inet/htons_test.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "src/__support/endian_internal.h" -#include "src/network/htons.h" -#include "src/network/ntohs.h" +#include "src/arpa/inet/htons.h" +#include "src/arpa/inet/ntohs.h" #include "test/UnitTest/Test.h" TEST(LlvmLibcHtons, SmokeTest) { diff --git a/libc/test/src/network/ntohl_test.cpp b/libc/test/src/arpa/inet/ntohl_test.cpp similarity index 93% rename from libc/test/src/network/ntohl_test.cpp rename to libc/test/src/arpa/inet/ntohl_test.cpp index b72456b7200e5..42562486d5c00 100644 --- a/libc/test/src/network/ntohl_test.cpp +++ b/libc/test/src/arpa/inet/ntohl_test.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "src/__support/endian_internal.h" -#include "src/network/htonl.h" -#include "src/network/ntohl.h" +#include "src/arpa/inet/htonl.h" +#include "src/arpa/inet/ntohl.h" #include "test/UnitTest/Test.h" TEST(LlvmLibcNtohl, SmokeTest) { diff --git a/libc/test/src/network/ntohs_test.cpp b/libc/test/src/arpa/inet/ntohs_test.cpp similarity index 93% rename from libc/test/src/network/ntohs_test.cpp rename to libc/test/src/arpa/inet/ntohs_test.cpp index 1104356076b94..38b2c8d8fe40f 100644 --- a/libc/test/src/network/ntohs_test.cpp +++ b/libc/test/src/arpa/inet/ntohs_test.cpp @@ -7,8 +7,8 @@ //===----------------------------------------------------------------------===// #include "src/__support/endian_internal.h" -#include "src/network/htons.h" -#include "src/network/ntohs.h" +#include "src/arpa/inet/htons.h" +#include "src/arpa/inet/ntohs.h" #include "test/UnitTest/Test.h" TEST(LlvmLibcNtohs, SmokeTest) { diff --git a/libc/test/src/complex/CImagTest.h b/libc/test/src/complex/CImagTest.h index 6d2f935002669..408460d97dfc6 100644 --- a/libc/test/src/complex/CImagTest.h +++ b/libc/test/src/complex/CImagTest.h @@ -38,9 +38,14 @@ class CImagTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { neg_min_denormal); EXPECT_FP_EQ(func(CFPT(1241.112 + max_denormal * 1.0i)), max_denormal); EXPECT_FP_EQ(func(CFPT(121.121 + zero * 1.0i)), zero); - EXPECT_FP_EQ(func(CFPT(neg_zero + zero * 1.0i)), zero); - EXPECT_FP_EQ(func(CFPT(neg_zero + neg_zero * 1.0i)), neg_zero); - EXPECT_FP_EQ(func(CFPT(zero + neg_zero * 1.0i)), neg_zero); + EXPECT_FP_EQ(func(CFPT(0.0 + 0.0i)), 0.0); + EXPECT_FP_EQ(func(CFPT(-0.0 + 0.0i)), 0.0); + EXPECT_FP_EQ(func(CFPT(0.0 - 0.0i)), -0.0); + EXPECT_FP_EQ(func(CFPT(-0.0 - 0.0i)), -0.0); + EXPECT_FP_EQ(func(CFPT(0.0)), 0.0); + EXPECT_FP_EQ(func(CFPT(-0.0)), 0.0); + EXPECT_FP_EQ(func(CFPT(0.0i)), 0.0); + EXPECT_FP_EQ(func(CFPT(-0.0i)), -0.0); } void testRoundedNumbers(CImagFunc func) { diff --git a/libc/test/src/complex/CMakeLists.txt b/libc/test/src/complex/CMakeLists.txt index 8f49e6d79e179..0c668d9e1e8b9 100644 --- a/libc/test/src/complex/CMakeLists.txt +++ b/libc/test/src/complex/CMakeLists.txt @@ -1,5 +1,65 @@ add_custom_target(libc-complex-unittests) +add_libc_test( + conj_test + SUITE + libc-complex-unittests + SRCS + conj_test.cpp + DEPENDS + libc.src.complex.conj + LINK_LIBRARIES + LibcFPTestHelpers +) + +add_libc_test( + conjf_test + SUITE + libc-complex-unittests + SRCS + conjf_test.cpp + DEPENDS + libc.src.complex.conjf + LINK_LIBRARIES + LibcFPTestHelpers +) + +add_libc_test( + conjl_test + SUITE + libc-complex-unittests + SRCS + conjl_test.cpp + DEPENDS + libc.src.complex.conjl + LINK_LIBRARIES + LibcFPTestHelpers +) + +add_libc_test( + conjf16_test + SUITE + libc-complex-unittests + SRCS + conjf16_test.cpp + DEPENDS + libc.src.complex.conjf16 + LINK_LIBRARIES + LibcFPTestHelpers +) + +add_libc_test( + conjf128_test + SUITE + libc-complex-unittests + SRCS + conjf128_test.cpp + DEPENDS + libc.src.complex.conjf128 + LINK_LIBRARIES + LibcFPTestHelpers +) + add_libc_test( creal_test SUITE diff --git a/libc/test/src/complex/CRealTest.h b/libc/test/src/complex/CRealTest.h index a25555b506e22..80eafc9975f4c 100644 --- a/libc/test/src/complex/CRealTest.h +++ b/libc/test/src/complex/CRealTest.h @@ -37,8 +37,14 @@ class CRealTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { EXPECT_FP_EQ(func(CFPT(neg_min_denormal + 781.134i)), neg_min_denormal); EXPECT_FP_EQ(func(CFPT(max_denormal + 1241.112i)), max_denormal); EXPECT_FP_EQ(func(CFPT(zero + 121.121i)), zero); - EXPECT_FP_EQ(func(CFPT(neg_zero + neg_zero * 1.0i)), neg_zero); - EXPECT_FP_EQ(func(CFPT(neg_zero + zero * 1.0i)), zero); + EXPECT_FP_EQ(func(CFPT(0.0 + 0.0i)), 0.0); + EXPECT_FP_EQ(func(CFPT(-0.0 + 0.0i)), 0.0); + EXPECT_FP_EQ(func(CFPT(0.0 - 0.0i)), 0.0); + EXPECT_FP_EQ(func(CFPT(-0.0 - 0.0i)), -0.0); + EXPECT_FP_EQ(func(CFPT(0.0)), 0.0); + EXPECT_FP_EQ(func(CFPT(-0.0)), -0.0); + EXPECT_FP_EQ(func(CFPT(0.0i)), 0.0); + EXPECT_FP_EQ(func(CFPT(-0.0i)), -0.0); } void testRoundedNumbers(CRealFunc func) { diff --git a/libc/test/src/complex/ConjTest.h b/libc/test/src/complex/ConjTest.h new file mode 100644 index 0000000000000..da4fb4fd137c8 --- /dev/null +++ b/libc/test/src/complex/ConjTest.h @@ -0,0 +1,131 @@ +//===-- Utility class to test different flavors of conj ---------*- 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_TEST_SRC_COMPLEX_CONJTEST_H +#define LLVM_LIBC_TEST_SRC_COMPLEX_CONJTEST_H + +#include "test/UnitTest/FEnvSafeTest.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" + +#include "hdr/math_macros.h" + +template +class ConjTest : public LIBC_NAMESPACE::testing::FEnvSafeTest { + + DECLARE_SPECIAL_CONSTANTS(FPT) + +public: + typedef CFPT (*ConjFunc)(CFPT); + + void testSpecialNumbers(ConjFunc func) { + EXPECT_CFP_EQ(func(CFPT(aNaN + 67.123i)), CFPT(aNaN - 67.123i)); + EXPECT_CFP_EQ(func(CFPT(neg_aNaN + 78.319i)), CFPT(neg_aNaN - 78.319i)); + EXPECT_CFP_EQ(func(CFPT(sNaN + 7813.131i)), CFPT(sNaN - 7813.131i)); + EXPECT_CFP_EQ(func(CFPT(neg_sNaN + 7824.152i)), CFPT(neg_sNaN - 7824.152i)); + EXPECT_CFP_EQ(func(CFPT(inf + 9024.2442i)), CFPT(inf - 9024.2442i)); + EXPECT_CFP_EQ(func(CFPT(neg_inf + 8923.124i)), CFPT(neg_inf - 8923.124i)); + EXPECT_CFP_EQ(func(CFPT(min_normal + 782.124i)), + CFPT(min_normal - 782.124i)); + EXPECT_CFP_EQ(func(CFPT(max_normal + 2141.2352i)), + CFPT(max_normal - 2141.2352i)); + EXPECT_CFP_EQ(func(CFPT(neg_max_normal + 341.134i)), + CFPT(neg_max_normal - 341.134i)); + EXPECT_CFP_EQ(func(CFPT(min_denormal + 781.142i)), + CFPT(min_denormal - 781.142i)); + EXPECT_CFP_EQ(func(CFPT(neg_min_denormal + 781.134i)), + CFPT(neg_min_denormal - 781.134i)); + EXPECT_CFP_EQ(func(CFPT(max_denormal + 1241.112i)), + CFPT(max_denormal - 1241.112i)); + EXPECT_CFP_EQ(func(CFPT(zero + 121.121i)), CFPT(zero - 121.121i)); + EXPECT_CFP_EQ(func(CFPT(67.123 + aNaN * 1.0i)), CFPT(67.123 - aNaN * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(78.319 + neg_aNaN * 1.0i)), + CFPT(78.319 - neg_aNaN * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(7813.131 + sNaN * 1.0i)), + CFPT(7813.131 - sNaN * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(7824.152 + neg_sNaN * 1.0i)), + CFPT(7824.152 - neg_sNaN * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(9024.2442 + inf * 1.0i)), + CFPT(9024.2442 - inf * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(8923.124 + neg_inf * 1.0i)), + CFPT(8923.124 - neg_inf * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(782.124 + min_normal * 1.0i)), + CFPT(782.124 - min_normal * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(2141.2352 + max_normal * 1.0i)), + CFPT(2141.2352 - max_normal * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(341.134 + neg_max_normal * 1.0i)), + CFPT(341.134 - neg_max_normal * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(781.142 + min_denormal * 1.0i)), + CFPT(781.142 - min_denormal * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(781.134 + neg_min_denormal * 1.0i)), + CFPT(781.134 - neg_min_denormal * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(1241.112 + max_denormal * 1.0i)), + CFPT(1241.112 - max_denormal * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(121.121 + zero * 1.0i)), + CFPT(121.121 - zero * 1.0i)); + EXPECT_CFP_EQ(func(CFPT(0.0 - 0.0i)), CFPT(0.0 + 0.0i)); + EXPECT_CFP_EQ(func(CFPT(0.0 + 0.0i)), CFPT(0.0 - 0.0i)); + // This test passes because the conjugate of -0.0 - 0.0i is CMPLX(-0.0, 0.0) + // which cannot be represented as -0.0 + 0.0i because -0.0 + 0.0i is + // actually CMPLX(-0.0, 0.0) + CMPLX(0.0, 0.0) = 0.0 + 0.0i so to represent + // CMPLX(-0.0, 0.0), we use -0.0 + EXPECT_CFP_EQ(func(CFPT(-0.0 - 0.0i)), CFPT(-0.0)); + // This test passes because -0.0 + 0.0i is actually + // CMPLX(-0.0, 0.0) + CMPLX(0.0, 0.0) = CMPLX(-0.0 + 0.0, 0.0) = 0.0 + 0.0i + EXPECT_CFP_EQ(func(CFPT(-0.0 + 0.0i)), CFPT(0.0 - 0.0i)); + EXPECT_CFP_EQ(func(CFPT(0.0)), CFPT(0.0 - 0.0i)); + EXPECT_CFP_EQ(func(CFPT(-0.0)), CFPT(-0.0 - 0.0i)); + EXPECT_CFP_EQ(func(CFPT(0.0i)), CFPT(0.0 - 0.0i)); + EXPECT_CFP_EQ(func(CFPT(-0.0i)), CFPT(-0.0)); + } + + void testRoundedNumbers(ConjFunc func) { + EXPECT_CFP_EQ(func((CFPT)(4523.1413 + 12413.1414i)), + CFPT(4523.1413 - 12413.1414i)); + EXPECT_CFP_EQ(func((CFPT)(-4523.1413 + 12413.1414i)), + CFPT(-4523.1413 - 12413.1414i)); + EXPECT_CFP_EQ(func((CFPT)(4523.1413 - 12413.1414i)), + CFPT(4523.1413 + 12413.1414i)); + EXPECT_CFP_EQ(func((CFPT)(-4523.1413 - 12413.1414i)), + CFPT(-4523.1413 + 12413.1414i)); + + EXPECT_CFP_EQ(func((CFPT)(3210.5678 + 9876.5432i)), + CFPT(3210.5678 - 9876.5432i)); + EXPECT_CFP_EQ(func((CFPT)(-3210.5678 + 9876.5432i)), + CFPT(-3210.5678 - 9876.5432i)); + EXPECT_CFP_EQ(func((CFPT)(3210.5678 - 9876.5432i)), + CFPT(3210.5678 + 9876.5432i)); + EXPECT_CFP_EQ(func((CFPT)(-3210.5678 - 9876.5432i)), + CFPT(-3210.5678 + 9876.5432i)); + + EXPECT_CFP_EQ(func((CFPT)(1234.4321 + 4321.1234i)), + CFPT(1234.4321 - 4321.1234i)); + EXPECT_CFP_EQ(func((CFPT)(-1234.4321 + 4321.1234i)), + CFPT(-1234.4321 - 4321.1234i)); + EXPECT_CFP_EQ(func((CFPT)(1234.4321 - 4321.1234i)), + CFPT(1234.4321 + 4321.1234i)); + EXPECT_CFP_EQ(func((CFPT)(-1234.4321 - 4321.1234i)), + CFPT(-1234.4321 + 4321.1234i)); + + EXPECT_CFP_EQ(func((CFPT)(6789.1234 + 8765.6789i)), + CFPT(6789.1234 - 8765.6789i)); + EXPECT_CFP_EQ(func((CFPT)(-6789.1234 + 8765.6789i)), + CFPT(-6789.1234 - 8765.6789i)); + EXPECT_CFP_EQ(func((CFPT)(6789.1234 - 8765.6789i)), + CFPT(6789.1234 + 8765.6789i)); + EXPECT_CFP_EQ(func((CFPT)(-6789.1234 - 8765.6789i)), + CFPT(-6789.1234 + 8765.6789i)); + } +}; + +#define LIST_CONJ_TESTS(U, T, func) \ + using LlvmLibcConjTest = ConjTest; \ + TEST_F(LlvmLibcConjTest, SpecialNumbers) { testSpecialNumbers(&func); } \ + TEST_F(LlvmLibcConjTest, RoundedNumbers) { testRoundedNumbers(&func); } + +#endif // LLVM_LIBC_TEST_SRC_COMPLEX_CONJTEST_H diff --git a/libc/test/src/complex/conj_test.cpp b/libc/test/src/complex/conj_test.cpp new file mode 100644 index 0000000000000..97445fa065088 --- /dev/null +++ b/libc/test/src/complex/conj_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for conj ------------------------------------------------===// +// +// 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 "ConjTest.h" + +#include "src/complex/conj.h" + +LIST_CONJ_TESTS(_Complex double, double, LIBC_NAMESPACE::conj) diff --git a/libc/test/src/complex/conjf128_test.cpp b/libc/test/src/complex/conjf128_test.cpp new file mode 100644 index 0000000000000..a1feb9ff31fdc --- /dev/null +++ b/libc/test/src/complex/conjf128_test.cpp @@ -0,0 +1,17 @@ +//===-- Unittests for conjf128 --------------------------------------------===// +// +// 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 "ConjTest.h" + +#include "src/complex/conjf128.h" + +#if defined(LIBC_TYPES_HAS_CFLOAT128) + +LIST_CONJ_TESTS(cfloat128, float128, LIBC_NAMESPACE::conjf128) + +#endif // LIBC_TYPES_HAS_CFLOAT128 diff --git a/libc/test/src/complex/conjf16_test.cpp b/libc/test/src/complex/conjf16_test.cpp new file mode 100644 index 0000000000000..0de9f448e8681 --- /dev/null +++ b/libc/test/src/complex/conjf16_test.cpp @@ -0,0 +1,17 @@ +//===-- Unittests for conjf16 ---------------------------------------------===// +// +// 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 "ConjTest.h" + +#include "src/complex/conjf16.h" + +#if defined(LIBC_TYPES_HAS_CFLOAT16) + +LIST_CONJ_TESTS(cfloat16, float16, LIBC_NAMESPACE::conjf16) + +#endif // LIBC_TYPES_HAS_CFLOAT16 diff --git a/libc/test/src/complex/conjf_test.cpp b/libc/test/src/complex/conjf_test.cpp new file mode 100644 index 0000000000000..34b00b37996c3 --- /dev/null +++ b/libc/test/src/complex/conjf_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for conjf -----------------------------------------------===// +// +// 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 "ConjTest.h" + +#include "src/complex/conjf.h" + +LIST_CONJ_TESTS(_Complex float, float, LIBC_NAMESPACE::conjf) diff --git a/libc/test/src/complex/conjl_test.cpp b/libc/test/src/complex/conjl_test.cpp new file mode 100644 index 0000000000000..ec299f9631547 --- /dev/null +++ b/libc/test/src/complex/conjl_test.cpp @@ -0,0 +1,13 @@ +//===-- Unittests for conjl -----------------------------------------------===// +// +// 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 "ConjTest.h" + +#include "src/complex/conjl.h" + +LIST_CONJ_TESTS(_Complex long double, long double, LIBC_NAMESPACE::conjl) diff --git a/libc/test/src/ctype/isalnum_test.cpp b/libc/test/src/ctype/isalnum_test.cpp index 18ddd2b14b8c8..cfc54e95e922d 100644 --- a/libc/test/src/ctype/isalnum_test.cpp +++ b/libc/test/src/ctype/isalnum_test.cpp @@ -11,16 +11,7 @@ #include "test/UnitTest/Test.h" -TEST(LlvmLibcIsAlNum, SimpleTest) { - EXPECT_NE(LIBC_NAMESPACE::isalnum('a'), 0); - EXPECT_NE(LIBC_NAMESPACE::isalnum('B'), 0); - EXPECT_NE(LIBC_NAMESPACE::isalnum('3'), 0); - - EXPECT_EQ(LIBC_NAMESPACE::isalnum(' '), 0); - EXPECT_EQ(LIBC_NAMESPACE::isalnum('?'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isalnum('\0'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isalnum(-1), 0); -} +namespace { // TODO: Merge the ctype tests using this framework. constexpr char ALNUM_ARRAY[] = { @@ -38,6 +29,19 @@ bool in_span(int ch, LIBC_NAMESPACE::cpp::span arr) { return false; } +} // namespace + +TEST(LlvmLibcIsAlNum, SimpleTest) { + EXPECT_NE(LIBC_NAMESPACE::isalnum('a'), 0); + EXPECT_NE(LIBC_NAMESPACE::isalnum('B'), 0); + EXPECT_NE(LIBC_NAMESPACE::isalnum('3'), 0); + + EXPECT_EQ(LIBC_NAMESPACE::isalnum(' '), 0); + EXPECT_EQ(LIBC_NAMESPACE::isalnum('?'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isalnum('\0'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isalnum(-1), 0); +} + TEST(LlvmLibcIsAlNum, DefaultLocale) { // Loops through all characters, verifying that numbers and letters // return non-zero integer and everything else returns a zero. diff --git a/libc/test/src/ctype/isalpha_test.cpp b/libc/test/src/ctype/isalpha_test.cpp index e54b580dbe264..1e439cf973e35 100644 --- a/libc/test/src/ctype/isalpha_test.cpp +++ b/libc/test/src/ctype/isalpha_test.cpp @@ -11,16 +11,7 @@ #include "test/UnitTest/Test.h" -TEST(LlvmLibcIsAlpha, SimpleTest) { - EXPECT_NE(LIBC_NAMESPACE::isalpha('a'), 0); - EXPECT_NE(LIBC_NAMESPACE::isalpha('B'), 0); - - EXPECT_EQ(LIBC_NAMESPACE::isalpha('3'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isalpha(' '), 0); - EXPECT_EQ(LIBC_NAMESPACE::isalpha('?'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isalpha('\0'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isalpha(-1), 0); -} +namespace { // TODO: Merge the ctype tests using this framework. constexpr char ALPHA_ARRAY[] = { @@ -37,6 +28,19 @@ bool in_span(int ch, LIBC_NAMESPACE::cpp::span arr) { return false; } +} // namespace + +TEST(LlvmLibcIsAlpha, SimpleTest) { + EXPECT_NE(LIBC_NAMESPACE::isalpha('a'), 0); + EXPECT_NE(LIBC_NAMESPACE::isalpha('B'), 0); + + EXPECT_EQ(LIBC_NAMESPACE::isalpha('3'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isalpha(' '), 0); + EXPECT_EQ(LIBC_NAMESPACE::isalpha('?'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isalpha('\0'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isalpha(-1), 0); +} + TEST(LlvmLibcIsAlpha, DefaultLocale) { // Loops through all characters, verifying that letters return a // non-zero integer and everything else returns zero. diff --git a/libc/test/src/ctype/isdigit_test.cpp b/libc/test/src/ctype/isdigit_test.cpp index adea55e59c74d..0ee132d7f8515 100644 --- a/libc/test/src/ctype/isdigit_test.cpp +++ b/libc/test/src/ctype/isdigit_test.cpp @@ -11,16 +11,7 @@ #include "test/UnitTest/Test.h" -TEST(LlvmLibcIsDigit, SimpleTest) { - EXPECT_NE(LIBC_NAMESPACE::isdigit('3'), 0); - - EXPECT_EQ(LIBC_NAMESPACE::isdigit('a'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isdigit('B'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isdigit(' '), 0); - EXPECT_EQ(LIBC_NAMESPACE::isdigit('?'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isdigit('\0'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isdigit(-1), 0); -} +namespace { // TODO: Merge the ctype tests using this framework. constexpr char DIGIT_ARRAY[] = { @@ -34,6 +25,19 @@ bool in_span(int ch, LIBC_NAMESPACE::cpp::span arr) { return false; } +} // namespace + +TEST(LlvmLibcIsDigit, SimpleTest) { + EXPECT_NE(LIBC_NAMESPACE::isdigit('3'), 0); + + EXPECT_EQ(LIBC_NAMESPACE::isdigit('a'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isdigit('B'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isdigit(' '), 0); + EXPECT_EQ(LIBC_NAMESPACE::isdigit('?'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isdigit('\0'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isdigit(-1), 0); +} + TEST(LlvmLibcIsDigit, DefaultLocale) { // Loops through all characters, verifying that numbers and letters // return non-zero integer and everything else returns a zero. diff --git a/libc/test/src/ctype/islower_test.cpp b/libc/test/src/ctype/islower_test.cpp index f9414bd8cbd09..f877171abb9a3 100644 --- a/libc/test/src/ctype/islower_test.cpp +++ b/libc/test/src/ctype/islower_test.cpp @@ -11,16 +11,7 @@ #include "test/UnitTest/Test.h" -TEST(LlvmLibcIsLower, SimpleTest) { - EXPECT_NE(LIBC_NAMESPACE::islower('a'), 0); - - EXPECT_EQ(LIBC_NAMESPACE::islower('B'), 0); - EXPECT_EQ(LIBC_NAMESPACE::islower('3'), 0); - EXPECT_EQ(LIBC_NAMESPACE::islower(' '), 0); - EXPECT_EQ(LIBC_NAMESPACE::islower('?'), 0); - EXPECT_EQ(LIBC_NAMESPACE::islower('\0'), 0); - EXPECT_EQ(LIBC_NAMESPACE::islower(-1), 0); -} +namespace { // TODO: Merge the ctype tests using this framework. constexpr char LOWER_ARRAY[] = { @@ -35,6 +26,19 @@ bool in_span(int ch, LIBC_NAMESPACE::cpp::span arr) { return false; } +} // namespace + +TEST(LlvmLibcIsLower, SimpleTest) { + EXPECT_NE(LIBC_NAMESPACE::islower('a'), 0); + + EXPECT_EQ(LIBC_NAMESPACE::islower('B'), 0); + EXPECT_EQ(LIBC_NAMESPACE::islower('3'), 0); + EXPECT_EQ(LIBC_NAMESPACE::islower(' '), 0); + EXPECT_EQ(LIBC_NAMESPACE::islower('?'), 0); + EXPECT_EQ(LIBC_NAMESPACE::islower('\0'), 0); + EXPECT_EQ(LIBC_NAMESPACE::islower(-1), 0); +} + TEST(LlvmLibcIsLower, DefaultLocale) { // Loops through all characters, verifying that numbers and letters // return non-zero integer and everything else returns a zero. diff --git a/libc/test/src/ctype/isupper_test.cpp b/libc/test/src/ctype/isupper_test.cpp index 94def1a9dcccd..151ed23f0ac99 100644 --- a/libc/test/src/ctype/isupper_test.cpp +++ b/libc/test/src/ctype/isupper_test.cpp @@ -11,16 +11,7 @@ #include "test/UnitTest/Test.h" -TEST(LlvmLibcIsUpper, SimpleTest) { - EXPECT_NE(LIBC_NAMESPACE::isupper('B'), 0); - - EXPECT_EQ(LIBC_NAMESPACE::isupper('a'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isupper('3'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isupper(' '), 0); - EXPECT_EQ(LIBC_NAMESPACE::isupper('?'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isupper('\0'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isupper(-1), 0); -} +namespace { // TODO: Merge the ctype tests using this framework. constexpr char UPPER_ARRAY[] = { @@ -35,6 +26,19 @@ bool in_span(int ch, LIBC_NAMESPACE::cpp::span arr) { return false; } +} // namespace + +TEST(LlvmLibcIsUpper, SimpleTest) { + EXPECT_NE(LIBC_NAMESPACE::isupper('B'), 0); + + EXPECT_EQ(LIBC_NAMESPACE::isupper('a'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isupper('3'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isupper(' '), 0); + EXPECT_EQ(LIBC_NAMESPACE::isupper('?'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isupper('\0'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isupper(-1), 0); +} + TEST(LlvmLibcIsUpper, DefaultLocale) { // Loops through all characters, verifying that numbers and letters // return non-zero integer and everything else returns a zero. diff --git a/libc/test/src/ctype/isxdigit_test.cpp b/libc/test/src/ctype/isxdigit_test.cpp index d7253d549907b..ec58f0da49223 100644 --- a/libc/test/src/ctype/isxdigit_test.cpp +++ b/libc/test/src/ctype/isxdigit_test.cpp @@ -11,17 +11,7 @@ #include "test/UnitTest/Test.h" -TEST(LlvmLibcIsXdigit, SimpleTest) { - EXPECT_NE(LIBC_NAMESPACE::isxdigit('a'), 0); - EXPECT_NE(LIBC_NAMESPACE::isxdigit('B'), 0); - EXPECT_NE(LIBC_NAMESPACE::isxdigit('3'), 0); - - EXPECT_EQ(LIBC_NAMESPACE::isxdigit('z'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isxdigit(' '), 0); - EXPECT_EQ(LIBC_NAMESPACE::isxdigit('?'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isxdigit('\0'), 0); - EXPECT_EQ(LIBC_NAMESPACE::isxdigit(-1), 0); -} +namespace { // TODO: Merge the ctype tests using this framework. constexpr char XDIGIT_ARRAY[] = { @@ -36,6 +26,20 @@ bool in_span(int ch, LIBC_NAMESPACE::cpp::span arr) { return false; } +} // namespace + +TEST(LlvmLibcIsXdigit, SimpleTest) { + EXPECT_NE(LIBC_NAMESPACE::isxdigit('a'), 0); + EXPECT_NE(LIBC_NAMESPACE::isxdigit('B'), 0); + EXPECT_NE(LIBC_NAMESPACE::isxdigit('3'), 0); + + EXPECT_EQ(LIBC_NAMESPACE::isxdigit('z'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isxdigit(' '), 0); + EXPECT_EQ(LIBC_NAMESPACE::isxdigit('?'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isxdigit('\0'), 0); + EXPECT_EQ(LIBC_NAMESPACE::isxdigit(-1), 0); +} + TEST(LlvmLibcIsXdigit, DefaultLocale) { // Loops through all characters, verifying that numbers and letters // return non-zero integer and everything else returns a zero. diff --git a/libc/test/src/ctype/tolower_test.cpp b/libc/test/src/ctype/tolower_test.cpp index 59432c43297b3..fbcc5b8ee0d9d 100644 --- a/libc/test/src/ctype/tolower_test.cpp +++ b/libc/test/src/ctype/tolower_test.cpp @@ -11,16 +11,7 @@ #include "test/UnitTest/Test.h" -TEST(LlvmLibcToLower, SimpleTest) { - EXPECT_EQ(LIBC_NAMESPACE::tolower('a'), int('a')); - EXPECT_EQ(LIBC_NAMESPACE::tolower('B'), int('b')); - EXPECT_EQ(LIBC_NAMESPACE::tolower('3'), int('3')); - - EXPECT_EQ(LIBC_NAMESPACE::tolower(' '), int(' ')); - EXPECT_EQ(LIBC_NAMESPACE::tolower('?'), int('?')); - EXPECT_EQ(LIBC_NAMESPACE::tolower('\0'), int('\0')); - EXPECT_EQ(LIBC_NAMESPACE::tolower(-1), int(-1)); -} +namespace { // TODO: Merge the ctype tests using this framework. // Invariant: UPPER_ARR and LOWER_ARR are both the complete alphabet in the same @@ -45,6 +36,19 @@ int span_index(int ch, LIBC_NAMESPACE::cpp::span arr) { return -1; } +} // namespace + +TEST(LlvmLibcToLower, SimpleTest) { + EXPECT_EQ(LIBC_NAMESPACE::tolower('a'), int('a')); + EXPECT_EQ(LIBC_NAMESPACE::tolower('B'), int('b')); + EXPECT_EQ(LIBC_NAMESPACE::tolower('3'), int('3')); + + EXPECT_EQ(LIBC_NAMESPACE::tolower(' '), int(' ')); + EXPECT_EQ(LIBC_NAMESPACE::tolower('?'), int('?')); + EXPECT_EQ(LIBC_NAMESPACE::tolower('\0'), int('\0')); + EXPECT_EQ(LIBC_NAMESPACE::tolower(-1), int(-1)); +} + TEST(LlvmLibcToLower, DefaultLocale) { for (int ch = -255; ch < 255; ++ch) { int char_index = span_index(ch, UPPER_ARR); diff --git a/libc/test/src/ctype/toupper_test.cpp b/libc/test/src/ctype/toupper_test.cpp index 045b00bbb4b93..409b3cd96ed1e 100644 --- a/libc/test/src/ctype/toupper_test.cpp +++ b/libc/test/src/ctype/toupper_test.cpp @@ -11,16 +11,7 @@ #include "test/UnitTest/Test.h" -TEST(LlvmLibcToUpper, SimpleTest) { - EXPECT_EQ(LIBC_NAMESPACE::toupper('a'), int('A')); - EXPECT_EQ(LIBC_NAMESPACE::toupper('B'), int('B')); - EXPECT_EQ(LIBC_NAMESPACE::toupper('3'), int('3')); - - EXPECT_EQ(LIBC_NAMESPACE::toupper(' '), int(' ')); - EXPECT_EQ(LIBC_NAMESPACE::toupper('?'), int('?')); - EXPECT_EQ(LIBC_NAMESPACE::toupper('\0'), int('\0')); - EXPECT_EQ(LIBC_NAMESPACE::toupper(-1), int(-1)); -} +namespace { // TODO: Merge the ctype tests using this framework. // Invariant: UPPER_ARR and LOWER_ARR are both the complete alphabet in the same @@ -45,6 +36,19 @@ int span_index(int ch, LIBC_NAMESPACE::cpp::span arr) { return -1; } +} // namespace + +TEST(LlvmLibcToUpper, SimpleTest) { + EXPECT_EQ(LIBC_NAMESPACE::toupper('a'), int('A')); + EXPECT_EQ(LIBC_NAMESPACE::toupper('B'), int('B')); + EXPECT_EQ(LIBC_NAMESPACE::toupper('3'), int('3')); + + EXPECT_EQ(LIBC_NAMESPACE::toupper(' '), int(' ')); + EXPECT_EQ(LIBC_NAMESPACE::toupper('?'), int('?')); + EXPECT_EQ(LIBC_NAMESPACE::toupper('\0'), int('\0')); + EXPECT_EQ(LIBC_NAMESPACE::toupper(-1), int(-1)); +} + TEST(LlvmLibcToUpper, DefaultLocale) { for (int ch = -255; ch < 255; ++ch) { int char_index = span_index(ch, LOWER_ARR); diff --git a/libc/test/src/math/CMakeLists.txt b/libc/test/src/math/CMakeLists.txt index ea75720df4f43..16e7d4957ba11 100644 --- a/libc/test/src/math/CMakeLists.txt +++ b/libc/test/src/math/CMakeLists.txt @@ -28,6 +28,17 @@ add_fp_unittest( libc.src.__support.FPUtil.fp_bits ) +add_fp_unittest( + cosf16_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + cosf16_test.cpp + DEPENDS + libc.src.math.cosf16 +) + add_fp_unittest( cospif_test NEED_MPFR @@ -1549,6 +1560,19 @@ add_fp_unittest( libc.src.math.sqrtf16 ) +add_fp_unittest( + sqrtf128_test + NEED_MPFR + SUITE + libc-math-unittests + SRCS + sqrtf128_test.cpp + HDRS + SqrtTest.h + DEPENDS + libc.src.math.sqrtf128 +) + add_fp_unittest( generic_sqrtf_test NEED_MPFR diff --git a/libc/test/src/math/cosf16_test.cpp b/libc/test/src/math/cosf16_test.cpp new file mode 100644 index 0000000000000..9e4687f0325c4 --- /dev/null +++ b/libc/test/src/math/cosf16_test.cpp @@ -0,0 +1,40 @@ +//===-- Exhaustive test for cosf16 ----------------------------------------===// +// +// 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/math/cosf16.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" +#include "utils/MPFRWrapper/MPFRUtils.h" + +using LlvmLibcCosf16Test = LIBC_NAMESPACE::testing::FPTest; + +namespace mpfr = LIBC_NAMESPACE::testing::mpfr; + +// Range: [0, Inf] +static constexpr uint16_t POS_START = 0x0000U; +static constexpr uint16_t POS_STOP = 0x7c00u; + +// Range: [-Inf, 0] +static constexpr uint16_t NEG_START = 0x8000U; +static constexpr uint16_t NEG_STOP = 0xfc00U; + +TEST_F(LlvmLibcCosf16Test, PositiveRange) { + for (uint16_t v = POS_START; v <= POS_STOP; ++v) { + float16 x = FPBits(v).get_val(); + EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Cos, x, + LIBC_NAMESPACE::cosf16(x), 0.5); + } +} + +TEST_F(LlvmLibcCosf16Test, NegativeRange) { + for (uint16_t v = NEG_START; v <= NEG_STOP; ++v) { + float16 x = FPBits(v).get_val(); + EXPECT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Cos, x, + LIBC_NAMESPACE::cosf16(x), 0.5); + } +} diff --git a/libc/test/src/math/smoke/CMakeLists.txt b/libc/test/src/math/smoke/CMakeLists.txt index 2c1c4dba73846..31f85a3ecfd27 100644 --- a/libc/test/src/math/smoke/CMakeLists.txt +++ b/libc/test/src/math/smoke/CMakeLists.txt @@ -12,6 +12,17 @@ add_fp_unittest( libc.src.math.cosf ) +add_fp_unittest( + cosf16_test + SUITE + libc-math-smoke-tests + SRCS + cosf16_test.cpp + DEPENDS + libc.src.errno.errno + libc.src.math.cosf16 +) + add_fp_unittest( cospif_test SUITE diff --git a/libc/test/src/math/smoke/cosf16_test.cpp b/libc/test/src/math/smoke/cosf16_test.cpp new file mode 100644 index 0000000000000..9a51d1015da34 --- /dev/null +++ b/libc/test/src/math/smoke/cosf16_test.cpp @@ -0,0 +1,33 @@ +//===-- Unittests for cosf16 ----------------------------------------------===// +// +// 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/errno/libc_errno.h" +#include "src/math/cosf16.h" +#include "test/UnitTest/FPMatcher.h" +#include "test/UnitTest/Test.h" + +using LlvmLibcCosf16Test = LIBC_NAMESPACE::testing::FPTest; + +TEST_F(LlvmLibcCosf16Test, SpecialNumbers) { + LIBC_NAMESPACE::libc_errno = 0; + + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf16(aNaN)); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::cosf16(zero)); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ(1.0f, LIBC_NAMESPACE::cosf16(neg_zero)); + EXPECT_MATH_ERRNO(0); + + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf16(inf)); + EXPECT_MATH_ERRNO(EDOM); + + EXPECT_FP_EQ(aNaN, LIBC_NAMESPACE::cosf16(neg_inf)); + EXPECT_MATH_ERRNO(EDOM); +} diff --git a/libc/test/src/math/sqrtf128_test.cpp b/libc/test/src/math/sqrtf128_test.cpp new file mode 100644 index 0000000000000..25229f834d33c --- /dev/null +++ b/libc/test/src/math/sqrtf128_test.cpp @@ -0,0 +1,43 @@ +//===-- Unittests for sqrtf128 --------------------------------------------===// +// +// 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 "SqrtTest.h" + +#include "src/math/sqrtf128.h" + +#include "src/__support/integer_literals.h" + +LIST_SQRT_TESTS(float128, LIBC_NAMESPACE::sqrtf128) + +TEST_F(LlvmLibcSqrtTest, SpecialInputs) { + constexpr float128 INPUTS[] = { + 0x0.000000dee2f5b6a26c8f07f05442p-16382q, + 0x0.000000c86d174c5ad8ae54a548e7p-16382q, + 0x0.000020ab15cfe0b8e488e128f535p-16382q, + 0x0.0000219e97732a9970f2511989bap-16382q, + 0x0.000026e477546ae99ef57066f9fdp-16382q, + 0x0.00002d0f88d27a496b3e533f5067p-16382q, + 0x1.0000000000000000000000000001p+0q, + 0x1.0000000000000000000000000003p+0q, + 0x1.0000000000000000000000000005p+0q, + 0x1.2af17a4ae6f93d11310c49c11b59p+0q, + 0x1.c4f5074269525063a26051a0ad27p+0q, + 0x1.035cb5f298a801dc4be9b1f8cd97p+1q, + 0x1.274be02380427e709beab4dedeb4p+1q, + 0x1.64e797cfdbaa3f7e2f33279dbc6p+1q, + 0x1.d78d8352b48608b510bfd5c75315p+1q, + 0x1.fffffffffffffffffffffffffffbp+1q, + 0x1.fffffffffffffffffffffffffffdp+1q, + 0x1.ffffffffffffffffffffffffffffp+1q, + }; + + for (auto input : INPUTS) { + ASSERT_MPFR_MATCH_ALL_ROUNDING(mpfr::Operation::Sqrt, input, + LIBC_NAMESPACE::sqrtf128(input), 0.5); + } +} diff --git a/libc/test/src/network/CMakeLists.txt b/libc/test/src/network/CMakeLists.txt deleted file mode 100644 index 222205dfe247a..0000000000000 --- a/libc/test/src/network/CMakeLists.txt +++ /dev/null @@ -1,53 +0,0 @@ -add_custom_target(libc_network_unittests) - -add_libc_unittest( - htonl - SUITE - libc_network_unittests - SRCS - htonl_test.cpp - CXX_STANDARD - 20 - DEPENDS - libc.src.network.htonl - libc.src.network.ntohl -) - -add_libc_unittest( - htons - SUITE - libc_network_unittests - SRCS - htons_test.cpp - CXX_STANDARD - 20 - DEPENDS - libc.src.network.htons - libc.src.network.ntohs -) - -add_libc_unittest( - ntohl - SUITE - libc_network_unittests - SRCS - ntohl_test.cpp - CXX_STANDARD - 20 - DEPENDS - libc.src.network.htonl - libc.src.network.ntohl -) - -add_libc_unittest( - ntohs - SUITE - libc_network_unittests - SRCS - ntohs_test.cpp - CXX_STANDARD - 20 - DEPENDS - libc.src.network.htons - libc.src.network.ntohs -) diff --git a/libc/test/src/stdlib/CMakeLists.txt b/libc/test/src/stdlib/CMakeLists.txt index ff6034e43e9f6..4ca2043ab4c9b 100644 --- a/libc/test/src/stdlib/CMakeLists.txt +++ b/libc/test/src/stdlib/CMakeLists.txt @@ -431,8 +431,8 @@ if(LLVM_LIBC_FULL_BUILD) libc.src.stdlib.quick_exit ) - # Only the GPU has an in-tree 'malloc' implementation. - if(LIBC_TARGET_OS_IS_GPU) + # Only baremetal and GPU has an in-tree 'malloc' implementation. + if(LIBC_TARGET_OS_IS_BAREMETAL OR LIBC_TARGET_OS_IS_GPU) add_libc_test( malloc_test HERMETIC_TEST_ONLY diff --git a/libc/test/src/stdlib/StrtolTest.h b/libc/test/src/stdlib/StrtolTest.h index 6cfaddcbedeb6..ed302f14d03ef 100644 --- a/libc/test/src/stdlib/StrtolTest.h +++ b/libc/test/src/stdlib/StrtolTest.h @@ -200,8 +200,8 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test { char small_string[4] = {'\0', '\0', '\0', '\0'}; for (int base = 2; base <= 36; ++base) { for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = - LIBC_NAMESPACE::internal::int_to_b36_char(first_digit); + small_string[0] = static_cast( + LIBC_NAMESPACE::internal::int_to_b36_char(first_digit)); if (first_digit < base) { LIBC_NAMESPACE::libc_errno = 0; ASSERT_EQ(func(small_string, nullptr, base), @@ -217,11 +217,11 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test { for (int base = 2; base <= 36; ++base) { for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = - LIBC_NAMESPACE::internal::int_to_b36_char(first_digit); + small_string[0] = static_cast( + LIBC_NAMESPACE::internal::int_to_b36_char(first_digit)); for (int second_digit = 0; second_digit <= 36; ++second_digit) { - small_string[1] = - LIBC_NAMESPACE::internal::int_to_b36_char(second_digit); + small_string[1] = static_cast( + LIBC_NAMESPACE::internal::int_to_b36_char(second_digit)); if (first_digit < base && second_digit < base) { LIBC_NAMESPACE::libc_errno = 0; ASSERT_EQ( @@ -244,14 +244,14 @@ struct StrtoTest : public LIBC_NAMESPACE::testing::Test { for (int base = 2; base <= 36; ++base) { for (int first_digit = 0; first_digit <= 36; ++first_digit) { - small_string[0] = - LIBC_NAMESPACE::internal::int_to_b36_char(first_digit); + small_string[0] = static_cast( + LIBC_NAMESPACE::internal::int_to_b36_char(first_digit)); for (int second_digit = 0; second_digit <= 36; ++second_digit) { - small_string[1] = - LIBC_NAMESPACE::internal::int_to_b36_char(second_digit); + small_string[1] = static_cast( + LIBC_NAMESPACE::internal::int_to_b36_char(second_digit)); for (int third_digit = 0; third_digit <= limit; ++third_digit) { - small_string[2] = - LIBC_NAMESPACE::internal::int_to_b36_char(third_digit); + small_string[2] = static_cast( + LIBC_NAMESPACE::internal::int_to_b36_char(third_digit)); if (first_digit < base && second_digit < base && third_digit < base) { diff --git a/libc/test/src/string/CMakeLists.txt b/libc/test/src/string/CMakeLists.txt index b6b59a689cc8f..a675373938e99 100644 --- a/libc/test/src/string/CMakeLists.txt +++ b/libc/test/src/string/CMakeLists.txt @@ -2,35 +2,12 @@ add_custom_target(libc-string-tests) add_subdirectory(memory_utils) -add_libc_test( - bcopy_test - SUITE - libc-string-tests - SRCS - bcopy_test.cpp - DEPENDS - libc.src.string.bcopy - LINK_LIBRARIES - LibcMemoryHelpers -) - add_header_library( strchr_test_support HDRS StrchrTest.h ) -add_libc_test( - index_test - SUITE - libc-string-tests - SRCS - index_test.cpp - DEPENDS - libc.src.string.index - .strchr_test_support -) - add_libc_test( memccpy_test SUITE @@ -81,17 +58,6 @@ add_libc_test( libc.src.string.memrchr ) -add_libc_test( - rindex_test - SUITE - libc-string-tests - SRCS - rindex_test.cpp - DEPENDS - libc.src.string.rindex - .strchr_test_support -) - add_libc_test( stpcpy_test SUITE @@ -153,16 +119,6 @@ add_libc_test( libc.src.string.strcmp ) -add_libc_test( - strcasecmp_test - SUITE - libc-string-tests - SRCS - strcasecmp_test.cpp - DEPENDS - libc.src.string.strcasecmp -) - add_libc_test( strcasestr_test SUITE @@ -287,16 +243,6 @@ add_libc_test( libc.src.string.strncmp ) -add_libc_test( - strncasecmp_test - SUITE - libc-string-tests - SRCS - strncasecmp_test.cpp - DEPENDS - libc.src.string.strncasecmp -) - add_libc_test( strncpy_test SUITE @@ -428,39 +374,7 @@ add_libc_test( libc.src.string.memset_explicit ) -# Tests all implementations that can run on the target CPU. -function(add_libc_multi_impl_test name) - get_property(fq_implementations GLOBAL PROPERTY ${name}_implementations) - foreach(fq_config_name IN LISTS fq_implementations) - get_target_property(required_cpu_features ${fq_config_name} REQUIRE_CPU_FEATURES) - cpu_supports(can_run "${required_cpu_features}") - if(can_run) - string(FIND ${fq_config_name} "." last_dot_loc REVERSE) - math(EXPR name_loc "${last_dot_loc} + 1") - string(SUBSTRING ${fq_config_name} ${name_loc} -1 target_name) - add_libc_test( - ${target_name}_test - SUITE - libc-string-tests - COMPILE_OPTIONS - ${LIBC_COMPILE_OPTIONS_NATIVE} - LINK_LIBRARIES - LibcMemoryHelpers - ${ARGN} - DEPENDS - ${fq_config_name} - libc.src.__support.macros.sanitizer - ) - get_fq_target_name(${fq_config_name}_test fq_target_name) - else() - message(STATUS "Skipping test for '${fq_config_name}' insufficient host cpu features '${required_cpu_features}'") - endif() - endforeach() -endfunction() - -add_libc_multi_impl_test(bcmp SRCS bcmp_test.cpp) -add_libc_multi_impl_test(bzero SRCS bzero_test.cpp) -add_libc_multi_impl_test(memcmp SRCS memcmp_test.cpp) -add_libc_multi_impl_test(memcpy SRCS memcpy_test.cpp) -add_libc_multi_impl_test(memmove SRCS memmove_test.cpp) -add_libc_multi_impl_test(memset SRCS memset_test.cpp) +add_libc_multi_impl_test(memcmp libc-string-tests SRCS memcmp_test.cpp) +add_libc_multi_impl_test(memcpy libc-string-tests SRCS memcpy_test.cpp) +add_libc_multi_impl_test(memmove libc-string-tests SRCS memmove_test.cpp) +add_libc_multi_impl_test(memset libc-string-tests SRCS memset_test.cpp) diff --git a/libc/test/src/strings/CMakeLists.txt b/libc/test/src/strings/CMakeLists.txt new file mode 100644 index 0000000000000..10f96b8531f68 --- /dev/null +++ b/libc/test/src/strings/CMakeLists.txt @@ -0,0 +1,58 @@ +add_custom_target(libc-strings-tests) + +add_libc_test( + bcopy_test + SUITE + libc-strings-tests + SRCS + bcopy_test.cpp + DEPENDS + libc.src.strings.bcopy + LINK_LIBRARIES + LibcMemoryHelpers +) + +add_libc_test( + index_test + SUITE + libc-strings-tests + SRCS + index_test.cpp + DEPENDS + libc.src.strings.index + libc.test.src.string.strchr_test_support +) + +add_libc_test( + rindex_test + SUITE + libc-strings-tests + SRCS + rindex_test.cpp + DEPENDS + libc.src.strings.rindex + libc.test.src.string.strchr_test_support +) + +add_libc_test( + strcasecmp_test + SUITE + libc-strings-tests + SRCS + strcasecmp_test.cpp + DEPENDS + libc.src.strings.strcasecmp +) + +add_libc_test( + strncasecmp_test + SUITE + libc-strings-tests + SRCS + strncasecmp_test.cpp + DEPENDS + libc.src.strings.strncasecmp +) + +add_libc_multi_impl_test(bcmp libc-strings-tests SRCS bcmp_test.cpp) +add_libc_multi_impl_test(bzero libc-strings-tests SRCS bzero_test.cpp) diff --git a/libc/test/src/string/bcmp_test.cpp b/libc/test/src/strings/bcmp_test.cpp similarity index 95% rename from libc/test/src/string/bcmp_test.cpp rename to libc/test/src/strings/bcmp_test.cpp index c639040685e19..794f9a1b8bd9d 100644 --- a/libc/test/src/string/bcmp_test.cpp +++ b/libc/test/src/strings/bcmp_test.cpp @@ -6,11 +6,11 @@ // //===----------------------------------------------------------------------===// -#include "memory_utils/memory_check_utils.h" #include "src/__support/macros/config.h" -#include "src/string/bcmp.h" +#include "src/strings/bcmp.h" #include "test/UnitTest/Test.h" #include "test/UnitTest/TestLogger.h" +#include "test/src/string/memory_utils/memory_check_utils.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/test/src/string/bcopy_test.cpp b/libc/test/src/strings/bcopy_test.cpp similarity index 97% rename from libc/test/src/string/bcopy_test.cpp rename to libc/test/src/strings/bcopy_test.cpp index 04772bb5d8ad7..f6bb859b4ae9f 100644 --- a/libc/test/src/string/bcopy_test.cpp +++ b/libc/test/src/strings/bcopy_test.cpp @@ -6,13 +6,13 @@ // //===----------------------------------------------------------------------===// -#include "src/__support/macros/config.h" -#include "src/string/bcopy.h" +#include "src/strings/bcopy.h" -#include "memory_utils/memory_check_utils.h" #include "src/__support/CPP/span.h" +#include "src/__support/macros/config.h" #include "test/UnitTest/MemoryMatcher.h" #include "test/UnitTest/Test.h" +#include "test/src/string/memory_utils/memory_check_utils.h" using LIBC_NAMESPACE::cpp::array; using LIBC_NAMESPACE::cpp::span; diff --git a/libc/test/src/string/bzero_test.cpp b/libc/test/src/strings/bzero_test.cpp similarity index 91% rename from libc/test/src/string/bzero_test.cpp rename to libc/test/src/strings/bzero_test.cpp index a24043613bed7..4d4112f4be8ee 100644 --- a/libc/test/src/string/bzero_test.cpp +++ b/libc/test/src/strings/bzero_test.cpp @@ -6,10 +6,10 @@ // //===----------------------------------------------------------------------===// -#include "memory_utils/memory_check_utils.h" #include "src/__support/macros/config.h" -#include "src/string/bzero.h" +#include "src/strings/bzero.h" #include "test/UnitTest/Test.h" +#include "test/src/string/memory_utils/memory_check_utils.h" namespace LIBC_NAMESPACE_DECL { diff --git a/libc/test/src/string/index_test.cpp b/libc/test/src/strings/index_test.cpp similarity index 86% rename from libc/test/src/string/index_test.cpp rename to libc/test/src/strings/index_test.cpp index 88953205009d7..fc4cd2b31c55d 100644 --- a/libc/test/src/string/index_test.cpp +++ b/libc/test/src/strings/index_test.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "StrchrTest.h" +#include "test/src/string/StrchrTest.h" -#include "src/string/index.h" +#include "src/strings/index.h" #include "test/UnitTest/Test.h" STRCHR_TEST(Index, LIBC_NAMESPACE::index) diff --git a/libc/test/src/string/rindex_test.cpp b/libc/test/src/strings/rindex_test.cpp similarity index 86% rename from libc/test/src/string/rindex_test.cpp rename to libc/test/src/strings/rindex_test.cpp index 10513919cffa2..d3b756fe5f6e5 100644 --- a/libc/test/src/string/rindex_test.cpp +++ b/libc/test/src/strings/rindex_test.cpp @@ -6,9 +6,9 @@ // //===----------------------------------------------------------------------===// -#include "StrchrTest.h" +#include "test/src/string/StrchrTest.h" -#include "src/string/rindex.h" +#include "src/strings/rindex.h" #include "test/UnitTest/Test.h" STRRCHR_TEST(Rindex, LIBC_NAMESPACE::rindex) diff --git a/libc/test/src/string/strcasecmp_test.cpp b/libc/test/src/strings/strcasecmp_test.cpp similarity index 97% rename from libc/test/src/string/strcasecmp_test.cpp rename to libc/test/src/strings/strcasecmp_test.cpp index df7888168c69e..cd29c213a7324 100644 --- a/libc/test/src/string/strcasecmp_test.cpp +++ b/libc/test/src/strings/strcasecmp_test.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/string/strcasecmp.h" +#include "src/strings/strcasecmp.h" #include "test/UnitTest/Test.h" TEST(LlvmLibcStrCaseCmpTest, EmptyStringsShouldReturnZero) { diff --git a/libc/test/src/string/strncasecmp_test.cpp b/libc/test/src/strings/strncasecmp_test.cpp similarity index 97% rename from libc/test/src/string/strncasecmp_test.cpp rename to libc/test/src/strings/strncasecmp_test.cpp index b4173c455de91..870574ed9507c 100644 --- a/libc/test/src/string/strncasecmp_test.cpp +++ b/libc/test/src/strings/strncasecmp_test.cpp @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#include "src/string/strncasecmp.h" +#include "src/strings/strncasecmp.h" #include "test/UnitTest/Test.h" TEST(LlvmLibcStrNCaseCmpTest, diff --git a/libc/test/src/sys/mman/linux/CMakeLists.txt b/libc/test/src/sys/mman/linux/CMakeLists.txt index 6362b46a6fe09..44ed11aadfe8b 100644 --- a/libc/test/src/sys/mman/linux/CMakeLists.txt +++ b/libc/test/src/sys/mman/linux/CMakeLists.txt @@ -181,24 +181,3 @@ add_libc_unittest( libc.hdr.fcntl_macros libc.test.UnitTest.ErrnoSetterMatcher ) - -add_libc_unittest( - process_mrelease_test - SUITE - libc_sys_mman_unittests - SRCS - process_mrelease_test.cpp - DEPENDS - libc.include.sys_mman - libc.include.sys_syscall - libc.src.errno.errno - libc.src.sys.mman.process_mrelease - libc.src.unistd.close - libc.src.signal.kill - libc.include.signal - libc.src.stdlib.exit - libc.src.signal.raise - libc.src.__support.OSUtil.osutil - libc.src.__support.threads.sleep - libc.test.UnitTest.ErrnoSetterMatcher -) diff --git a/libc/test/src/sys/mman/linux/process_mrelease_test.cpp b/libc/test/src/sys/mman/linux/process_mrelease_test.cpp deleted file mode 100644 index 865056c05f8db..0000000000000 --- a/libc/test/src/sys/mman/linux/process_mrelease_test.cpp +++ /dev/null @@ -1,72 +0,0 @@ -//===-- Unittests for process_mrelease ------------------------------------===// -// -// 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/OSUtil/syscall.h" // For internal syscall function. -#include "src/errno/libc_errno.h" -#include "src/signal/kill.h" -#include "src/signal/raise.h" -#include "src/stdlib/exit.h" -#include "src/sys/mman/process_mrelease.h" -#include "src/unistd/close.h" -#include "src/unistd/fork.h" -#include "test/UnitTest/ErrnoSetterMatcher.h" -#include "test/UnitTest/LibcTest.h" - -#include -#if defined(SYS_process_mrelease) && defined(SYS_pidfd_open) -using namespace LIBC_NAMESPACE::testing::ErrnoSetterMatcher; - -int pidfd_open(pid_t pid, unsigned int flags) { - return LIBC_NAMESPACE::syscall_impl(SYS_pidfd_open, pid, flags); -} - -TEST(LlvmLibcProcessMReleaseTest, NoError) { - pid_t child_pid = fork(); - EXPECT_GE(child_pid, 0); - - if (child_pid == 0) { - // pause the child process - LIBC_NAMESPACE::raise(SIGSTOP); - } else { - // Parent process: wait a bit and then kill the child. - // Give child process some time to start. - int pidfd = pidfd_open(child_pid, 0); - EXPECT_GE(pidfd, 0); - - // Send SIGKILL to child process - LIBC_NAMESPACE::kill(child_pid, SIGKILL); - - EXPECT_THAT(LIBC_NAMESPACE::process_mrelease(pidfd, 0), Succeeds()); - - LIBC_NAMESPACE::close(pidfd); - } -} - -TEST(LlvmLibcProcessMReleaseTest, ErrorNotKilled) { - pid_t child_pid = fork(); - EXPECT_GE(child_pid, 0); - - if (child_pid == 0) { - // pause the child process - LIBC_NAMESPACE::raise(SIGSTOP); - } else { - int pidfd = pidfd_open(child_pid, 0); - EXPECT_GE(pidfd, 0); - - EXPECT_THAT(LIBC_NAMESPACE::process_mrelease(pidfd, 0), Fails(EINVAL)); - - LIBC_NAMESPACE::kill(child_pid, SIGKILL); - - LIBC_NAMESPACE::close(pidfd); - } -} - -TEST(LlvmLibcProcessMReleaseTest, ErrorNonExistingPidfd) { - EXPECT_THAT(LIBC_NAMESPACE::process_mrelease(-1, 0), Fails(EBADF)); -} -#endif diff --git a/libc/test/src/time/CMakeLists.txt b/libc/test/src/time/CMakeLists.txt index 7151526b72b26..da3903f3e0e49 100644 --- a/libc/test/src/time/CMakeLists.txt +++ b/libc/test/src/time/CMakeLists.txt @@ -71,11 +71,21 @@ add_libc_test( SUITE libc_time_unittests SRCS - clock_gettime_test.cpp + clock_gettime_test.cpp DEPENDS libc.src.time.clock_gettime ) +add_libc_test( + clock_getres_test + SUITE + libc_time_unittests + SRCS + clock_getres_test.cpp + DEPENDS + libc.src.time.clock_getres +) + add_libc_unittest( difftime_test SUITE @@ -157,8 +167,8 @@ add_libc_unittest( SRCS time_test.cpp DEPENDS - libc.include.time libc.src.time.time + libc.src.__support.time.clock_gettime libc.src.errno.errno ) diff --git a/libc/test/src/time/clock_getres_test.cpp b/libc/test/src/time/clock_getres_test.cpp new file mode 100644 index 0000000000000..d8b3f01b37a38 --- /dev/null +++ b/libc/test/src/time/clock_getres_test.cpp @@ -0,0 +1,55 @@ +//===-- Unittests for clock_getres- ---------------------------------------===// +// +// 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/time_macros.h" +#include "src/time/clock_getres.h" +#include "test/UnitTest/ErrnoSetterMatcher.h" +#include "test/UnitTest/Test.h" + +using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Fails; +using LIBC_NAMESPACE::testing::ErrnoSetterMatcher::Succeeds; + +TEST(LlvmLibcClockGetRes, Invalid) { + timespec tp; + EXPECT_THAT(LIBC_NAMESPACE::clock_getres(-1, &tp), Fails(EINVAL)); +} + +TEST(LlvmLibcClockGetRes, NullSpec) { + EXPECT_THAT(LIBC_NAMESPACE::clock_getres(CLOCK_REALTIME, nullptr), + Succeeds()); +} + +TEST(LlvmLibcClockGetRes, Realtime) { + timespec tp; + EXPECT_THAT(LIBC_NAMESPACE::clock_getres(CLOCK_REALTIME, &tp), Succeeds()); + EXPECT_GE(tp.tv_sec, static_cast(0)); + EXPECT_GE(tp.tv_nsec, static_cast(0)); +} + +TEST(LlvmLibcClockGetRes, Monotonic) { + timespec tp; + ASSERT_THAT(LIBC_NAMESPACE::clock_getres(CLOCK_MONOTONIC, &tp), Succeeds()); + EXPECT_GE(tp.tv_sec, static_cast(0)); + EXPECT_GE(tp.tv_nsec, static_cast(0)); +} + +TEST(LlvmLibcClockGetRes, ProcessCpuTime) { + timespec tp; + ASSERT_THAT(LIBC_NAMESPACE::clock_getres(CLOCK_PROCESS_CPUTIME_ID, &tp), + Succeeds()); + EXPECT_GE(tp.tv_sec, static_cast(0)); + EXPECT_GE(tp.tv_nsec, static_cast(0)); +} + +TEST(LlvmLibcClockGetRes, ThreadCpuTime) { + timespec tp; + ASSERT_THAT(LIBC_NAMESPACE::clock_getres(CLOCK_THREAD_CPUTIME_ID, &tp), + Succeeds()); + EXPECT_GE(tp.tv_sec, static_cast(0)); + EXPECT_GE(tp.tv_nsec, static_cast(0)); +} diff --git a/libc/test/src/time/time_test.cpp b/libc/test/src/time/time_test.cpp index d3d4dc9a28515..7cdb4e834633e 100644 --- a/libc/test/src/time/time_test.cpp +++ b/libc/test/src/time/time_test.cpp @@ -9,8 +9,6 @@ #include "src/time/time_func.h" #include "test/UnitTest/Test.h" -#include - TEST(LlvmLibcTimeTest, SmokeTest) { time_t t1; time_t t2 = LIBC_NAMESPACE::time(&t1); diff --git a/libc/utils/MPFRWrapper/MPFRUtils.cpp b/libc/utils/MPFRWrapper/MPFRUtils.cpp index 00592c5cb15f3..0dac497bb779a 100644 --- a/libc/utils/MPFRWrapper/MPFRUtils.cpp +++ b/libc/utils/MPFRWrapper/MPFRUtils.cpp @@ -22,6 +22,13 @@ #include "mpfr_inc.h" +#ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +extern "C" { +int mpfr_set_float128(mpfr_ptr, float128, mpfr_rnd_t); +float128 mpfr_get_float128(mpfr_srcptr, mpfr_rnd_t); +} +#endif + template using FPBits = LIBC_NAMESPACE::fputil::FPBits; namespace LIBC_NAMESPACE_DECL { @@ -47,8 +54,18 @@ template <> struct ExtraPrecision { }; template <> struct ExtraPrecision { +#ifdef LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128 + static constexpr unsigned int VALUE = 512; +#else static constexpr unsigned int VALUE = 256; +#endif +}; + +#if defined(LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE) +template <> struct ExtraPrecision { + static constexpr unsigned int VALUE = 512; }; +#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE // If the ulp tolerance is less than or equal to 0.5, we would check that the // result is rounded correctly with respect to the rounding mode by using the @@ -134,6 +151,19 @@ class MPFRNumber { mpfr_set_ld(value, x, mpfr_rounding); } +#ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE + template , int> = 0> + explicit MPFRNumber(XType x, + unsigned int precision = ExtraPrecision::VALUE, + RoundingMode rounding = RoundingMode::Nearest) + : mpfr_precision(precision), + mpfr_rounding(get_mpfr_rounding_mode(rounding)) { + mpfr_init2(value, mpfr_precision); + mpfr_set_float128(value, x, mpfr_rounding); + } +#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE + template , int> = 0> explicit MPFRNumber(XType x, @@ -647,7 +677,7 @@ class MPFRNumber { // These functions are useful for debugging. template T as() const; - void dump(const char *msg) const { mpfr_printf("%s%.128Rf\n", msg, value); } + void dump(const char *msg) const { mpfr_printf("%s%.128g\n", msg, value); } // Return the ULP (units-in-the-last-place) difference between the // stored MPFR and a floating point number. @@ -770,6 +800,13 @@ template <> float16 MPFRNumber::as() const { } #endif +#ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +template <> float128 MPFRNumber::as() const { + return mpfr_get_float128(value, mpfr_rounding); +} + +#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE + namespace internal { template @@ -997,7 +1034,27 @@ template void explain_unary_operation_single_output_error(Operation op, double, template void explain_unary_operation_single_output_error(Operation op, long double, float16, double, RoundingMode); -#endif +#ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +template void explain_unary_operation_single_output_error(Operation op, + float128, float16, + double, RoundingMode); +#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +#endif // LIBC_TYPES_HAS_FLOAT16 + +#ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +template void explain_unary_operation_single_output_error(Operation op, + float128, float128, + double, RoundingMode); +template void explain_unary_operation_single_output_error(Operation op, + float128, float, + double, RoundingMode); +template void explain_unary_operation_single_output_error(Operation op, + float128, double, + double, RoundingMode); +template void explain_unary_operation_single_output_error(Operation op, + float128, long double, + double, RoundingMode); +#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE template void explain_unary_operation_two_outputs_error( @@ -1228,7 +1285,25 @@ template bool compare_unary_operation_single_output(Operation, double, float16, template bool compare_unary_operation_single_output(Operation, long double, float16, double, RoundingMode); -#endif +#ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +template bool compare_unary_operation_single_output(Operation, float128, + float16, double, + RoundingMode); +#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +#endif // LIBC_TYPES_HAS_FLOAT16 + +#ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +template bool compare_unary_operation_single_output(Operation, float128, + float128, double, + RoundingMode); +template bool compare_unary_operation_single_output(Operation, float128, float, + double, RoundingMode); +template bool compare_unary_operation_single_output(Operation, float128, double, + double, RoundingMode); +template bool compare_unary_operation_single_output(Operation, float128, + long double, double, + RoundingMode); +#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE template bool compare_unary_operation_two_outputs(Operation op, T input, @@ -1398,9 +1473,14 @@ template bool round_to_long(T x, long &result) { template bool round_to_long(float, long &); template bool round_to_long(double, long &); template bool round_to_long(long double, long &); + #ifdef LIBC_TYPES_HAS_FLOAT16 template bool round_to_long(float16, long &); -#endif +#endif // LIBC_TYPES_HAS_FLOAT16 + +#ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +template bool round_to_long(float128, long &); +#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE template bool round_to_long(T x, RoundingMode mode, long &result) { MPFRNumber mpfr(x); @@ -1410,9 +1490,14 @@ template bool round_to_long(T x, RoundingMode mode, long &result) { template bool round_to_long(float, RoundingMode, long &); template bool round_to_long(double, RoundingMode, long &); template bool round_to_long(long double, RoundingMode, long &); + #ifdef LIBC_TYPES_HAS_FLOAT16 template bool round_to_long(float16, RoundingMode, long &); -#endif +#endif // LIBC_TYPES_HAS_FLOAT16 + +#ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +template bool round_to_long(float128, RoundingMode, long &); +#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE template T round(T x, RoundingMode mode) { MPFRNumber mpfr(x); @@ -1423,9 +1508,14 @@ template T round(T x, RoundingMode mode) { template float round(float, RoundingMode); template double round(double, RoundingMode); template long double round(long double, RoundingMode); + #ifdef LIBC_TYPES_HAS_FLOAT16 template float16 round(float16, RoundingMode); -#endif +#endif // LIBC_TYPES_HAS_FLOAT16 + +#ifdef LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE +template float128 round(float128, RoundingMode); +#endif // LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE } // namespace mpfr } // namespace testing diff --git a/libc/utils/docgen/arpa/inet.yaml b/libc/utils/docgen/arpa/inet.yaml new file mode 100644 index 0000000000000..7f388cbbd0204 --- /dev/null +++ b/libc/utils/docgen/arpa/inet.yaml @@ -0,0 +1,18 @@ +functions: + htonl: + posix-definition: '' + htons: + posix-definition: '' + inet_addr: + posix-definition: '' + inet_ntoa: + posix-definition: '' + inet_ntop: + posix-definition: '' + inet_pton: + posix-definition: '' + ntohl: + posix-definition: '' + ntohs: + posix-definition: '' + diff --git a/libc/utils/docgen/assert.yaml b/libc/utils/docgen/assert.yaml new file mode 100644 index 0000000000000..0afd4e2d3c063 --- /dev/null +++ b/libc/utils/docgen/assert.yaml @@ -0,0 +1,7 @@ +macros: + __STDC_VERSION_ASSERT_H__: + c-definition: 7.2.1 + assert: + c-definition: 7.2.1 + in-latest-posix: '' + diff --git a/libc/utils/docgen/ctype.json b/libc/utils/docgen/ctype.json deleted file mode 100644 index af97e4bbbc0a2..0000000000000 --- a/libc/utils/docgen/ctype.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "functions": { - "isalnum": { - "c-definition": "7.4.1.1" - }, - "isalpha": { - "c-definition": "7.4.1.2" - }, - "isblank": { - "c-definition": "7.4.1.3" - }, - "iscntrl": { - "c-definition": "7.4.1.4" - }, - "isdigit": { - "c-definition": "7.4.1.5" - }, - "isgraph": { - "c-definition": "7.4.1.6" - }, - "islower": { - "c-definition": "7.4.1.7" - }, - "isprint": { - "c-definition": "7.4.1.8" - }, - "ispunct": { - "c-definition": "7.4.1.9" - }, - "isspace": { - "c-definition": "7.4.1.10" - }, - "isupper": { - "c-definition": "7.4.1.11" - }, - "isxdigit": { - "c-definition": "7.4.1.12" - }, - "tolower" : { - "c-definition": "7.4.2.1" - }, - "toupper": { - "c-definition": "7.4.2.2" - } - } -} - diff --git a/libc/utils/docgen/ctype.yaml b/libc/utils/docgen/ctype.yaml new file mode 100644 index 0000000000000..027d8f38c71f9 --- /dev/null +++ b/libc/utils/docgen/ctype.yaml @@ -0,0 +1,72 @@ +functions: + isalnum: + c-definition: 7.4.1.1 + in-latest-posix: '' + isalnum_l: + in-latest-posix: '' + isalpha: + c-definition: 7.4.1.2 + in-latest-posix: '' + isalpha_l: + in-latest-posix: '' + isblank: + c-definition: 7.4.1.3 + in-latest-posix: '' + isblank_l: + in-latest-posix: '' + iscntrl: + c-definition: 7.4.1.4 + in-latest-posix: '' + iscntrl_l: + in-latest-posix: '' + isdigit: + c-definition: 7.4.1.5 + in-latest-posix: '' + isdigit_l: + in-latest-posix: '' + isgraph: + c-definition: 7.4.1.6 + in-latest-posix: '' + isgraph_l: + in-latest-posix: '' + islower: + c-definition: 7.4.1.7 + in-latest-posix: '' + islower_l: + in-latest-posix: '' + isprint: + c-definition: 7.4.1.8 + in-latest-posix: '' + isprint_l: + in-latest-posix: '' + ispunct: + c-definition: 7.4.1.9 + in-latest-posix: '' + ispunct_l: + in-latest-posix: '' + isspace: + c-definition: 7.4.1.10 + in-latest-posix: '' + isspace_l: + in-latest-posix: '' + isupper: + c-definition: 7.4.1.11 + in-latest-posix: '' + isupper_l: + in-latest-posix: '' + isxdigit: + c-definition: 7.4.1.12 + in-latest-posix: '' + isxdigit_l: + in-latest-posix: '' + tolower: + c-definition: 7.4.2.1 + in-latest-posix: '' + tolower_l: + in-latest-posix: '' + toupper: + c-definition: 7.4.2.2 + in-latest-posix: '' + toupper_l: + in-latest-posix: '' + diff --git a/libc/utils/docgen/docgen.py b/libc/utils/docgen/docgen.py index af5d00a5cbf8c..09db284ef9282 100755 --- a/libc/utils/docgen/docgen.py +++ b/libc/utils/docgen/docgen.py @@ -10,8 +10,9 @@ from argparse import ArgumentParser, Namespace from pathlib import Path from typing import Dict +import os import sys -import json +import yaml from header import Header @@ -22,14 +23,14 @@ class DocgenAPIFormatError(Exception): def check_api(header: Header, api: Dict): """ - Checks that docgen json files are properly formatted. If there are any + Checks that docgen yaml files are properly formatted. If there are any fatal formatting errors, raises exceptions with error messages useful for fixing formatting. Warnings are printed to stderr on non-fatal formatting errors. The code that runs after ``check_api(api)`` is called expects that - ``check_api`` executed without raising formatting exceptions so the json + ``check_api`` executed without raising formatting exceptions so the yaml matches the formatting specified here. - The json file may contain: + The yaml file may contain: * an optional macros object * an optional functions object @@ -48,11 +49,15 @@ def check_api(header: Header, api: Dict): this should be a C standard section number. For the ``"posix-definition"`` property, this should be a link to the definition. - :param api: docgen json file contents parsed into a dict + :param api: docgen yaml file contents parsed into a dict """ errors = [] - cdef = "c-definition" - pdef = "posix-definition" + # We require entries to have at least one of these. + possible_keys = [ + "c-definition", + "in-latest-posix", + "removed-in-posix-2008", + ] # Validate macros if "macros" in api: @@ -65,8 +70,8 @@ def check_api(header: Header, api: Dict): macros = api["macros"] for name, obj in macros.items(): - if not (cdef in obj or pdef in obj): - err = f'error: Macro {name} does not contain at least one required property: "{cdef}" or "{pdef}"' + if not any(k in obj for k in possible_keys): + err = f"error: Macro {name} does not contain at least one required property: {possible_keys}" errors.append(err) # Validate functions @@ -79,8 +84,8 @@ def check_api(header: Header, api: Dict): fns = api["functions"] for name, obj in fns.items(): - if not (cdef in obj or pdef in obj): - err = f'error: function {name} does not contain at least one required property: "{cdef}" or "{pdef}"' + if not any(k in obj for k in possible_keys): + err = f"error: function {name} does not contain at least one required property: {possible_keys}" errors.append(err) if errors: @@ -88,8 +93,8 @@ def check_api(header: Header, api: Dict): def load_api(header: Header) -> Dict: - api = header.docgen_json.read_text(encoding="utf-8") - return json.loads(api) + api = header.docgen_yaml.read_text(encoding="utf-8") + return yaml.safe_load(api) def print_tbl_dir(name): @@ -103,7 +108,7 @@ def print_tbl_dir(name): * - {name} - Implemented - C23 Standard Section - - POSIX.1-2017 Standard Section""" + - POSIX Docs""" ) @@ -127,8 +132,14 @@ def print_functions_rst(header: Header, functions: Dict): else: print(" -") - if "posix-definition" in functions[name]: - print(f' - {functions[name]["posix-definition"]}') + if "in-latest-posix" in functions[name]: + print( + f" - `POSIX.1-2024 `__" + ) + elif "removed-in-posix-2008" in functions[name]: + print( + f" - `removed in POSIX.1-2008 `__" + ) else: print(" -") @@ -153,15 +164,20 @@ def print_macros_rst(header: Header, macros: Dict): else: print(" -") - if "posix-definition" in macros[name]: - print(f' - {macros[name]["posix-definition"]}') + if "in-latest-posix" in macros[name]: + print( + f" - `POSIX.1-2024 `__" + ) else: print(" -") print() def print_impl_status_rst(header: Header, api: Dict): - print(".. include:: check.rst\n") + if os.sep in header.name: + print(".. include:: ../../check.rst\n") + else: + print(".. include:: ../check.rst\n") print("=" * len(header.name)) print(header.name) @@ -176,10 +192,22 @@ def print_impl_status_rst(header: Header, api: Dict): print_functions_rst(header, api["functions"]) +# This code implicitly relies on docgen.py being in the same dir as the yaml +# files and is likely to need to be fixed when re-integrating docgen into +# hdrgen. +def get_choices() -> list: + choices = [] + for path in Path(__file__).parent.rglob("*.yaml"): + fname = path.with_suffix(".h").name + if path.parent != Path(__file__).parent: + fname = path.parent.name + os.sep + fname + choices.append(fname) + return choices + + def parse_args() -> Namespace: parser = ArgumentParser() - choices = [p.with_suffix(".h").name for p in Path(__file__).parent.glob("*.json")] - parser.add_argument("header_name", choices=choices) + parser.add_argument("header_name", choices=get_choices()) return parser.parse_args() diff --git a/libc/utils/docgen/errno.yaml b/libc/utils/docgen/errno.yaml new file mode 100644 index 0000000000000..da41552bc3a18 --- /dev/null +++ b/libc/utils/docgen/errno.yaml @@ -0,0 +1,14 @@ +macros: + EDOM: + c-definition: '7.5' + in-latest-posix: '' + EILSEQ: + c-definition: '7.5' + in-latest-posix: '' + ERANGE: + c-definition: '7.5' + in-latest-posix: '' + errno: + c-definition: '7.5' + in-latest-posix: '' + diff --git a/libc/utils/docgen/fenv.json b/libc/utils/docgen/fenv.json deleted file mode 100644 index 788b196c053bc..0000000000000 --- a/libc/utils/docgen/fenv.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "macros": { - "__STDC_VERSION_FENV_H__": { - "c-definition": "7.6.5" - }, - "FE_DIVBYZERO": { - "c-definition": "7.6.9" - }, - "FE_INEXACT": { - "c-definition": "7.6.9" - }, - "FE_INVALID": { - "c-definition": "7.6.9" - }, - "FE_OVERFLOW": { - "c-definition": "7.6.9" - }, - "FE_UNDERFLOW": { - "c-definition": "7.6.9" - }, - "FE_ALL_EXCEPT": { - "c-definition": "7.6.12" - }, - "FE_DFL_MODE": { - "c-definition": "7.6.11" - }, - "FE_DOWNARD": { - "c-definition": "7.6.13" - }, - "FE_TONEAREST": { - "c-definition": "7.6.13" - }, - "FE_TONEARESTFROMZERO": { - "c-definition": "7.6.13" - }, - "FE_TOWARDZERO": { - "c-definition": "7.6.13" - }, - "FE_UPWARD": { - "c-definition": "7.6.13" - }, - "FE_DEC_DOWNWARD": { - "c-definition": "7.6.14" - }, - "FE_DEC_TONEAREST": { - "c-definition": "7.6.14" - }, - "FE_DEC_TONEARESTFROMZERO": { - "c-definition": "7.6.14" - }, - "FE_DEC_TOWARDZERO": { - "c-definition": "7.6.14" - }, - "FE_DEC_UPWARD": { - "c-definition": "7.6.14" - }, - "FE_DFL_ENV": { - "c-definition": "7.6.17" - } - }, - "functions": { - "feclearexcept": { - "c-definition": "7.6.4.1" - }, - "fegetexceptflag": { - "c-definition": "7.6.4.2" - }, - "feraiseexcept": { - "c-definition": "7.6.4.3" - }, - "fesetexcept": { - "c-definition": "7.6.4.4" - }, - "fesetexceptflag": { - "c-definition": "7.6.4.5" - }, - "fetestexceptflag": { - "c-definition": "7.6.4.6" - }, - "fetestexcept": { - "c-definition": "7.6.4.7" - }, - "fegetmode": { - "c-definition": "7.6.5.1" - }, - "fegetround": { - "c-definition": "7.6.5.2" - }, - "fe_dec_getround": { - "c-definition": "7.6.5.3" - }, - "fesetmode": { - "c-definition": "7.6.5.4" - }, - "fesetround": { - "c-definition": "7.6.5.5" - }, - "fe_dec_setround": { - "c-definition": "7.6.5.6" - }, - "fegetenv": { - "c-definition": "7.6.6.1" - }, - "feholdexcept": { - "c-definition": "7.6.6.2" - }, - "fesetenv": { - "c-definition": "7.6.6.3" - }, - "feupdateenv": { - "c-definition": "7.6.6.4" - } - } -} diff --git a/libc/utils/docgen/fenv.yaml b/libc/utils/docgen/fenv.yaml new file mode 100644 index 0000000000000..1d73697f36bec --- /dev/null +++ b/libc/utils/docgen/fenv.yaml @@ -0,0 +1,97 @@ +functions: + fe_dec_getround: + c-definition: 7.6.5.3 + fe_dec_setround: + c-definition: 7.6.5.6 + feclearexcept: + c-definition: 7.6.4.1 + in-latest-posix: '' + fegetenv: + c-definition: 7.6.6.1 + in-latest-posix: '' + fegetexceptflag: + c-definition: 7.6.4.2 + in-latest-posix: '' + fegetmode: + c-definition: 7.6.5.1 + fegetround: + c-definition: 7.6.5.2 + in-latest-posix: '' + feholdexcept: + c-definition: 7.6.6.2 + in-latest-posix: '' + feraiseexcept: + c-definition: 7.6.4.3 + in-latest-posix: '' + fesetenv: + c-definition: 7.6.6.3 + in-latest-posix: '' + fesetexcept: + c-definition: 7.6.4.4 + fesetexceptflag: + c-definition: 7.6.4.5 + in-latest-posix: '' + fesetmode: + c-definition: 7.6.5.4 + fesetround: + c-definition: 7.6.5.5 + in-latest-posix: '' + fetestexcept: + c-definition: 7.6.4.7 + in-latest-posix: '' + fetestexceptflag: + c-definition: 7.6.4.6 + feupdateenv: + c-definition: 7.6.6.4 + in-latest-posix: '' +macros: + FE_ALL_EXCEPT: + c-definition: 7.6.12 + in-latest-posix: '' + FE_DEC_DOWNWARD: + c-definition: 7.6.14 + FE_DEC_TONEAREST: + c-definition: 7.6.14 + FE_DEC_TONEARESTFROMZERO: + c-definition: 7.6.14 + FE_DEC_TOWARDZERO: + c-definition: 7.6.14 + FE_DEC_UPWARD: + c-definition: 7.6.14 + FE_DFL_ENV: + c-definition: 7.6.17 + in-latest-posix: '' + FE_DFL_MODE: + c-definition: 7.6.11 + FE_DIVBYZERO: + c-definition: 7.6.9 + in-latest-posix: '' + FE_DOWNWARD: + c-definition: 7.6.13 + in-latest-posix: '' + FE_INEXACT: + c-definition: 7.6.9 + in-latest-posix: '' + FE_INVALID: + c-definition: 7.6.9 + in-latest-posix: '' + FE_OVERFLOW: + c-definition: 7.6.9 + in-latest-posix: '' + FE_TONEAREST: + c-definition: 7.6.13 + in-latest-posix: '' + FE_TONEARESTFROMZERO: + c-definition: 7.6.13 + FE_TOWARDZERO: + c-definition: 7.6.13 + in-latest-posix: '' + FE_UNDERFLOW: + c-definition: 7.6.9 + in-latest-posix: '' + FE_UPWARD: + c-definition: 7.6.13 + in-latest-posix: '' + __STDC_VERSION_FENV_H__: + c-definition: 7.6.5 + diff --git a/libc/utils/docgen/float.yaml b/libc/utils/docgen/float.yaml new file mode 100644 index 0000000000000..a8840b91be55b --- /dev/null +++ b/libc/utils/docgen/float.yaml @@ -0,0 +1,143 @@ +macros: + DBL_DECIMAL_DIG: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + DBL_DIG: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + DBL_EPSILON: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + DBL_HAS_SUBNORM: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + DBL_IS_IEC_60559: + c-definition: 5.3.5.3.3 + DBL_MANT_DIG: + c-definition: 5.3.5.3.3 + DBL_MAX: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + DBL_MAX_10_EXP: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + DBL_MAX_EXP: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + DBL_MIN: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + DBL_MIN_10_EXP: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + DBL_MIN_EXP: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + DBL_NORM_MAX: + c-definition: 5.3.5.3.3 + DBL_SNAN: + c-definition: 5.3.5.3.3 + DBL_TRUE_MIN: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + DECIMAL_DIG: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_DECIMAL_DIG: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_DIG: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_EPSILON: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_EVAL_METHOD: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_HAS_SUBNORM: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_IS_IEC_60559: + c-definition: 5.3.5.3.3 + FLT_MANT_DIG: + c-definition: 5.3.5.3.3 + FLT_MAX: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_MAX_10_EXP: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_MAX_EXP: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_MIN: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_MIN_10_EXP: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_MIN_EXP: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_NORM_MAX: + c-definition: 5.3.5.3.3 + FLT_RADIX: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_ROUNDS: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + FLT_SNAN: + c-definition: 5.3.5.3.3 + FLT_TRUE_MIN: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + INFINITY: + c-definition: 5.3.5.3.3 + LDBL_DECIMAL_DIG: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + LDBL_DIG: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + LDBL_EPSILON: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + LDBL_HAS_SUBNORM: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + LDBL_IS_IEC_60559: + c-definition: 5.3.5.3.3 + LDBL_MANT_DIG: + c-definition: 5.3.5.3.3 + LDBL_MAX: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + LDBL_MAX_10_EXP: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + LDBL_MAX_EXP: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + LDBL_MIN: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + LDBL_MIN_10_EXP: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + LDBL_MIN_EXP: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + LDBL_NORM_MAX: + c-definition: 5.3.5.3.3 + LDBL_SNAN: + c-definition: 5.3.5.3.3 + LDBL_TRUE_MIN: + c-definition: 5.3.5.3.3 + in-latest-posix: '' + NAN: + c-definition: 5.3.5.3.3 + __STDC_VERSION_FLOAT_H__: + c-definition: '7.7' + diff --git a/libc/utils/docgen/header.py b/libc/utils/docgen/header.py index dde210078db27..5bf524a64b69b 100644 --- a/libc/utils/docgen/header.py +++ b/libc/utils/docgen/header.py @@ -14,7 +14,7 @@ class Header: Maintains implementation information about a standard header file: * where does its implementation dir live * where is its macros file - * where is its docgen json file + * where is its docgen yaml file By convention, the macro-only part of a header file is in a header-specific file somewhere in the directory tree with root at @@ -42,7 +42,7 @@ def __init__(self, header_name: str): self.stem = header_name.rstrip(".h") self.docgen_root = Path(__file__).parent self.libc_root = self.docgen_root.parent.parent - self.docgen_json = self.docgen_root / Path(header_name).with_suffix(".json") + self.docgen_yaml = self.docgen_root / Path(header_name).with_suffix(".yaml") self.fns_dir = Path(self.libc_root, "src", self.stem) self.macros_dir = Path(self.libc_root, "include", "llvm-libc-macros") @@ -83,5 +83,10 @@ def __get_macro_files(self) -> Generator[Path, None, None]: macro file might be located in a subdirectory: libc/include/llvm-libc-macros/fcntl-macros.h libc/include/llvm-libc-macros/linux/fcntl-macros.h + + When a header would be nested in a dir (such as arpa/, sys/, etc) we + instead use a hyphen in the name. + libc/include/llvm-libc-macros/sys-mman-macros.h """ - return self.macros_dir.glob(f"**/{self.stem}-macros.h") + stem = self.stem.replace("/", "-") + return self.macros_dir.glob(f"**/{stem}-macros.h") diff --git a/libc/utils/docgen/inttypes.yaml b/libc/utils/docgen/inttypes.yaml new file mode 100644 index 0000000000000..cbf50592ef072 --- /dev/null +++ b/libc/utils/docgen/inttypes.yaml @@ -0,0 +1,20 @@ +functions: + imaxabs: + c-definition: 7.8.2.1 + in-latest-posix: '' + imaxdiv: + c-definition: 7.8.2.2 + in-latest-posix: '' + strtoimax: + c-definition: 7.8.2.3 + in-latest-posix: '' + strtoumax: + c-definition: 7.8.2.3 + in-latest-posix: '' + wcstoimax: + c-definition: 7.8.2.4 + in-latest-posix: '' + wcstoumax: + c-definition: 7.8.2.4 + in-latest-posix: '' + diff --git a/libc/utils/docgen/locale.yaml b/libc/utils/docgen/locale.yaml new file mode 100644 index 0000000000000..eea91a885ff49 --- /dev/null +++ b/libc/utils/docgen/locale.yaml @@ -0,0 +1,37 @@ +functions: + duplocale: + in-latest-posix: '' + freelocale: + in-latest-posix: '' + getlocalename_l: + in-latest-posix: '' + localeconv: + c-definition: 7.11.2.1 + in-latest-posix: '' + newlocale: + in-latest-posix: '' + setlocale: + c-definition: 7.11.1.1 + in-latest-posix: '' + uselocale: + in-latest-posix: '' +macros: + LC_ALL: + c-definition: '7.11' + in-latest-posix: '' + LC_COLLATE: + c-definition: '7.11' + in-latest-posix: '' + LC_CTYPE: + c-definition: '7.11' + in-latest-posix: '' + LC_MONETARY: + c-definition: '7.11' + in-latest-posix: '' + LC_NUMERIC: + c-definition: '7.11' + in-latest-posix: '' + LC_TIME: + c-definition: '7.11' + in-latest-posix: '' + diff --git a/libc/utils/docgen/setjmp.json b/libc/utils/docgen/setjmp.json deleted file mode 100644 index 0b9a4e65da4f6..0000000000000 --- a/libc/utils/docgen/setjmp.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "macros": { - "__STDC_VERSION_SETJMP_H__": { - "c-definition": "7.13.2" - } - }, - "functions": { - "setjmp": { - "c-definition": "7.13.1.1" - }, - "longjmp": { - "c-definition": "7.13.2.1" - } - } -} diff --git a/libc/utils/docgen/setjmp.yaml b/libc/utils/docgen/setjmp.yaml new file mode 100644 index 0000000000000..123739d1a6ceb --- /dev/null +++ b/libc/utils/docgen/setjmp.yaml @@ -0,0 +1,15 @@ +functions: + longjmp: + c-definition: 7.13.2.1 + in-latest-posix: '' + setjmp: + c-definition: 7.13.1.1 + in-latest-posix: '' + siglongjmp: + in-latest-posix: '' + sigsetjmp: + in-latest-posix: '' +macros: + __STDC_VERSION_SETJMP_H__: + c-definition: 7.13.2 + diff --git a/libc/utils/docgen/signal.json b/libc/utils/docgen/signal.json deleted file mode 100644 index 337b0c19717b7..0000000000000 --- a/libc/utils/docgen/signal.json +++ /dev/null @@ -1,152 +0,0 @@ -{ - "macros": { - "SIG_DFL": { - "c-definition": "7.14.3", - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIG_ERR": { - "c-definition": "7.14.3", - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIG_HOLD": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIG_IGN": { - "c-definition": "7.14.3", - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGRTMIN": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGRTMAX": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGABRT": { - "c-definition": "7.14.3", - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGALRM": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGBUS": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGCHLD": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGCONT": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGFPE": { - "c-definition": "7.14.3", - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGHUP": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGILL": { - "c-definition": "7.14.3", - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGINT": { - "c-definition": "7.14.3", - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGKILL": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGPIPE": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGPIPE": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGQUIT": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGSEGV": { - "c-definition": "7.14.3", - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGSTOP": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGTERM": { - "c-definition": "7.14.3", - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGTSTP": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGTTIN": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGTTOU": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGUSR1": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGUSR2": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGPOLL": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGPROF": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGSYS": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGTRAP": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGURG": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGVTALRM": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGXCPU": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - }, - "SIGXFSZ": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/signal.h.html" - } - }, - "functions": { - "signal": { - "c-definition": "7.14.1.1", - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/functions/signal.html" - }, - "raise": { - "c-definition": "7.14.2.1", - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/functions/raise.html" - }, - "kill": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/functions/kill.html" - }, - "sigaction": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaction.html" - }, - "sigaddset": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaddset.html" - }, - "sigaltstack": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigaltstack.html" - }, - "sigdelset": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigdelset.html" - }, - "sigemptyset": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigemptyset.html" - }, - "sigfillset": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigfillset.html" - }, - "sigprocmask": { - "posix-definition": "https://pubs.opengroup.org/onlinepubs/9699919799/functions/sigprocmask.html" - } - } -} diff --git a/libc/utils/docgen/signal.yaml b/libc/utils/docgen/signal.yaml new file mode 100644 index 0000000000000..da31a86b00eb0 --- /dev/null +++ b/libc/utils/docgen/signal.yaml @@ -0,0 +1,102 @@ +functions: + kill: + in-latest-posix: '' + raise: + c-definition: 7.14.2.1 + in-latest-posix: '' + sigaction: + in-latest-posix: '' + sigaddset: + in-latest-posix: '' + sigaltstack: + in-latest-posix: '' + sigdelset: + in-latest-posix: '' + sigemptyset: + in-latest-posix: '' + sigfillset: + in-latest-posix: '' + signal: + c-definition: 7.14.1.1 + in-latest-posix: '' + sigprocmask: + in-latest-posix: '' +macros: + SIGABRT: + c-definition: 7.14.3 + in-latest-posix: '' + SIGALRM: + in-latest-posix: '' + SIGBUS: + in-latest-posix: '' + SIGCHLD: + in-latest-posix: '' + SIGCONT: + in-latest-posix: '' + SIGFPE: + c-definition: 7.14.3 + in-latest-posix: '' + SIGHUP: + in-latest-posix: '' + SIGILL: + c-definition: 7.14.3 + in-latest-posix: '' + SIGINT: + c-definition: 7.14.3 + in-latest-posix: '' + SIGKILL: + in-latest-posix: '' + SIGPIPE: + in-latest-posix: '' + SIGPOLL: + in-latest-posix: '' + SIGPROF: + in-latest-posix: '' + SIGQUIT: + in-latest-posix: '' + SIGRTMAX: + in-latest-posix: '' + SIGRTMIN: + in-latest-posix: '' + SIGSEGV: + c-definition: 7.14.3 + in-latest-posix: '' + SIGSTOP: + in-latest-posix: '' + SIGSYS: + in-latest-posix: '' + SIGTERM: + c-definition: 7.14.3 + in-latest-posix: '' + SIGTRAP: + in-latest-posix: '' + SIGTSTP: + in-latest-posix: '' + SIGTTIN: + in-latest-posix: '' + SIGTTOU: + in-latest-posix: '' + SIGURG: + in-latest-posix: '' + SIGUSR1: + in-latest-posix: '' + SIGUSR2: + in-latest-posix: '' + SIGVTALRM: + in-latest-posix: '' + SIGXCPU: + in-latest-posix: '' + SIGXFSZ: + in-latest-posix: '' + SIG_DFL: + c-definition: 7.14.3 + in-latest-posix: '' + SIG_ERR: + c-definition: 7.14.3 + in-latest-posix: '' + SIG_HOLD: + in-latest-posix: '' + SIG_IGN: + c-definition: 7.14.3 + in-latest-posix: '' + diff --git a/libc/utils/docgen/stdbit.json b/libc/utils/docgen/stdbit.json deleted file mode 100644 index 25060c1ff9fd8..0000000000000 --- a/libc/utils/docgen/stdbit.json +++ /dev/null @@ -1,270 +0,0 @@ -{ - "macros": { - "__STDC_VERSION_STDBIT_H__": { - "c-definition": "7.18.1.2" - }, - "__STDC_ENDIAN_LITTLE__": { - "c-definition": "7.18.2.2" - }, - "__STDC_ENDIAN_BIG__": { - "c-definition": "7.18.2.2" - }, - "__STDC_ENDIAN_NATIVE__": { - "c-definition": "7.18.2.2" - }, - "stdc_leading_zeros": { - "c-definition": "7.18.3.1" - }, - "stdc_leading_ones": { - "c-definition": "7.18.4.1" - }, - "stdc_trailing_zeros": { - "c-definition": "7.18.5.1" - }, - "stdc_trailing_ones": { - "c-definition": "7.18.6.1" - }, - "stdc_first_leading_zero": { - "c-definition": "7.18.7.1" - }, - "stdc_first_leading_one": { - "c-definition": "7.18.8.1" - }, - "stdc_first_trailing_zero": { - "c-definition": "7.18.9.1" - }, - "stdc_first_trailing_one": { - "c-definition": "7.18.10.1" - }, - "stdc_count_zeros": { - "c-definition": "7.18.11.1" - }, - "stdc_count_ones": { - "c-definition": "7.18.12.1" - }, - "stdc_has_single_bit": { - "c-definition": "7.18.13.1" - }, - "stdc_bit_width": { - "c-definition": "7.18.14.1" - }, - "stdc_bit_floor": { - "c-definition": "7.18.15.1" - }, - "stdc_bit_ceil": { - "c-definition": "7.18.16.1" - } - }, - "functions": { - "stdc_leading_zeros_uc": { - "c-definition": "7.18.3" - }, - "stdc_leading_zeros_us": { - "c-definition": "7.18.3" - }, - "stdc_leading_zeros_ui": { - "c-definition": "7.18.3" - }, - "stdc_leading_zeros_ul": { - "c-definition": "7.18.3" - }, - "stdc_leading_zeros_ull": { - "c-definition": "7.18.3" - }, - "stdc_leading_ones_uc": { - "c-definition": "7.18.4" - }, - "stdc_leading_ones_us": { - "c-definition": "7.18.4" - }, - "stdc_leading_ones_ui": { - "c-definition": "7.18.4" - }, - "stdc_leading_ones_ul": { - "c-definition": "7.18.4" - }, - "stdc_leading_ones_ull": { - "c-definition": "7.18.4" - }, - "stdc_trailing_zeros_uc": { - "c-definition": "7.18.5" - }, - "stdc_trailing_zeros_us": { - "c-definition": "7.18.5" - }, - "stdc_trailing_zeros_ui": { - "c-definition": "7.18.5" - }, - "stdc_trailing_zeros_ul": { - "c-definition": "7.18.5" - }, - "stdc_trailing_zeros_ull": { - "c-definition": "7.18.5" - }, - "stdc_trailing_ones_uc": { - "c-definition": "7.18.6" - }, - "stdc_trailing_ones_us": { - "c-definition": "7.18.6" - }, - "stdc_trailing_ones_ui": { - "c-definition": "7.18.6" - }, - "stdc_trailing_ones_ul": { - "c-definition": "7.18.6" - }, - "stdc_trailing_ones_ull": { - "c-definition": "7.18.6" - }, - "stdc_first_leading_zero_uc": { - "c-definition": "7.18.7" - }, - "stdc_first_leading_zero_us": { - "c-definition": "7.18.7" - }, - "stdc_first_leading_zero_ui": { - "c-definition": "7.18.7" - }, - "stdc_first_leading_zero_ul": { - "c-definition": "7.18.7" - }, - "stdc_first_leading_zero_ull": { - "c-definition": "7.18.7" - }, - "stdc_first_leading_one_uc": { - "c-definition": "7.18.8" - }, - "stdc_first_leading_one_us": { - "c-definition": "7.18.8" - }, - "stdc_first_leading_one_ui": { - "c-definition": "7.18.8" - }, - "stdc_first_leading_one_ul": { - "c-definition": "7.18.8" - }, - "stdc_first_leading_one_ull": { - "c-definition": "7.18.8" - }, - "stdc_first_trailing_zero_uc": { - "c-definition": "7.18.9" - }, - "stdc_first_trailing_zero_us": { - "c-definition": "7.18.9" - }, - "stdc_first_trailing_zero_ui": { - "c-definition": "7.18.9" - }, - "stdc_first_trailing_zero_ul": { - "c-definition": "7.18.9" - }, - "stdc_first_trailing_zero_ull": { - "c-definition": "7.18.9" - }, - "stdc_first_trailing_one_uc": { - "c-definition": "7.18.10" - }, - "stdc_first_trailing_one_us": { - "c-definition": "7.18.10" - }, - "stdc_first_trailing_one_ui": { - "c-definition": "7.18.10" - }, - "stdc_first_trailing_one_ul": { - "c-definition": "7.18.10" - }, - "stdc_first_trailing_one_ull": { - "c-definition": "7.18.10" - }, - "stdc_count_zeros_uc": { - "c-definition": "7.18.11" - }, - "stdc_count_zeros_us": { - "c-definition": "7.18.11" - }, - "stdc_count_zeros_ui": { - "c-definition": "7.18.11" - }, - "stdc_count_zeros_ul": { - "c-definition": "7.18.11" - }, - "stdc_count_zeros_ull": { - "c-definition": "7.18.11" - }, - "stdc_count_ones_uc": { - "c-definition": "7.18.12" - }, - "stdc_count_ones_us": { - "c-definition": "7.18.12" - }, - "stdc_count_ones_ui": { - "c-definition": "7.18.12" - }, - "stdc_count_ones_ul": { - "c-definition": "7.18.12" - }, - "stdc_count_ones_ull": { - "c-definition": "7.18.12" - }, - "stdc_has_single_bit_uc": { - "c-definition": "7.18.13" - }, - "stdc_has_single_bit_us": { - "c-definition": "7.18.13" - }, - "stdc_has_single_bit_ui": { - "c-definition": "7.18.13" - }, - "stdc_has_single_bit_ul": { - "c-definition": "7.18.13" - }, - "stdc_has_single_bit_ull": { - "c-definition": "7.18.13" - }, - "stdc_bit_width_uc": { - "c-definition": "7.18.14" - }, - "stdc_bit_width_us": { - "c-definition": "7.18.14" - }, - "stdc_bit_width_ui": { - "c-definition": "7.18.14" - }, - "stdc_bit_width_ul": { - "c-definition": "7.18.14" - }, - "stdc_bit_width_ull": { - "c-definition": "7.18.14" - }, - "stdc_bit_floor_uc": { - "c-definition": "7.18.15" - }, - "stdc_bit_floor_us": { - "c-definition": "7.18.15" - }, - "stdc_bit_floor_ui": { - "c-definition": "7.18.15" - }, - "stdc_bit_floor_ul": { - "c-definition": "7.18.15" - }, - "stdc_bit_floor_ull": { - "c-definition": "7.18.15" - }, - "stdc_bit_ceil_uc": { - "c-definition": "7.18.16" - }, - "stdc_bit_ceil_us": { - "c-definition": "7.18.16" - }, - "stdc_bit_ceil_ui": { - "c-definition": "7.18.16" - }, - "stdc_bit_ceil_ul": { - "c-definition": "7.18.16" - }, - "stdc_bit_ceil_ull": { - "c-definition": "7.18.16" - } - } -} diff --git a/libc/utils/docgen/stdbit.yaml b/libc/utils/docgen/stdbit.yaml new file mode 100644 index 0000000000000..976221601e9cb --- /dev/null +++ b/libc/utils/docgen/stdbit.yaml @@ -0,0 +1,179 @@ +functions: + stdc_bit_ceil_uc: + c-definition: 7.18.16 + stdc_bit_ceil_ui: + c-definition: 7.18.16 + stdc_bit_ceil_ul: + c-definition: 7.18.16 + stdc_bit_ceil_ull: + c-definition: 7.18.16 + stdc_bit_ceil_us: + c-definition: 7.18.16 + stdc_bit_floor_uc: + c-definition: 7.18.15 + stdc_bit_floor_ui: + c-definition: 7.18.15 + stdc_bit_floor_ul: + c-definition: 7.18.15 + stdc_bit_floor_ull: + c-definition: 7.18.15 + stdc_bit_floor_us: + c-definition: 7.18.15 + stdc_bit_width_uc: + c-definition: 7.18.14 + stdc_bit_width_ui: + c-definition: 7.18.14 + stdc_bit_width_ul: + c-definition: 7.18.14 + stdc_bit_width_ull: + c-definition: 7.18.14 + stdc_bit_width_us: + c-definition: 7.18.14 + stdc_count_ones_uc: + c-definition: 7.18.12 + stdc_count_ones_ui: + c-definition: 7.18.12 + stdc_count_ones_ul: + c-definition: 7.18.12 + stdc_count_ones_ull: + c-definition: 7.18.12 + stdc_count_ones_us: + c-definition: 7.18.12 + stdc_count_zeros_uc: + c-definition: 7.18.11 + stdc_count_zeros_ui: + c-definition: 7.18.11 + stdc_count_zeros_ul: + c-definition: 7.18.11 + stdc_count_zeros_ull: + c-definition: 7.18.11 + stdc_count_zeros_us: + c-definition: 7.18.11 + stdc_first_leading_one_uc: + c-definition: 7.18.8 + stdc_first_leading_one_ui: + c-definition: 7.18.8 + stdc_first_leading_one_ul: + c-definition: 7.18.8 + stdc_first_leading_one_ull: + c-definition: 7.18.8 + stdc_first_leading_one_us: + c-definition: 7.18.8 + stdc_first_leading_zero_uc: + c-definition: 7.18.7 + stdc_first_leading_zero_ui: + c-definition: 7.18.7 + stdc_first_leading_zero_ul: + c-definition: 7.18.7 + stdc_first_leading_zero_ull: + c-definition: 7.18.7 + stdc_first_leading_zero_us: + c-definition: 7.18.7 + stdc_first_trailing_one_uc: + c-definition: 7.18.10 + stdc_first_trailing_one_ui: + c-definition: 7.18.10 + stdc_first_trailing_one_ul: + c-definition: 7.18.10 + stdc_first_trailing_one_ull: + c-definition: 7.18.10 + stdc_first_trailing_one_us: + c-definition: 7.18.10 + stdc_first_trailing_zero_uc: + c-definition: 7.18.9 + stdc_first_trailing_zero_ui: + c-definition: 7.18.9 + stdc_first_trailing_zero_ul: + c-definition: 7.18.9 + stdc_first_trailing_zero_ull: + c-definition: 7.18.9 + stdc_first_trailing_zero_us: + c-definition: 7.18.9 + stdc_has_single_bit_uc: + c-definition: 7.18.13 + stdc_has_single_bit_ui: + c-definition: 7.18.13 + stdc_has_single_bit_ul: + c-definition: 7.18.13 + stdc_has_single_bit_ull: + c-definition: 7.18.13 + stdc_has_single_bit_us: + c-definition: 7.18.13 + stdc_leading_ones_uc: + c-definition: 7.18.4 + stdc_leading_ones_ui: + c-definition: 7.18.4 + stdc_leading_ones_ul: + c-definition: 7.18.4 + stdc_leading_ones_ull: + c-definition: 7.18.4 + stdc_leading_ones_us: + c-definition: 7.18.4 + stdc_leading_zeros_uc: + c-definition: 7.18.3 + stdc_leading_zeros_ui: + c-definition: 7.18.3 + stdc_leading_zeros_ul: + c-definition: 7.18.3 + stdc_leading_zeros_ull: + c-definition: 7.18.3 + stdc_leading_zeros_us: + c-definition: 7.18.3 + stdc_trailing_ones_uc: + c-definition: 7.18.6 + stdc_trailing_ones_ui: + c-definition: 7.18.6 + stdc_trailing_ones_ul: + c-definition: 7.18.6 + stdc_trailing_ones_ull: + c-definition: 7.18.6 + stdc_trailing_ones_us: + c-definition: 7.18.6 + stdc_trailing_zeros_uc: + c-definition: 7.18.5 + stdc_trailing_zeros_ui: + c-definition: 7.18.5 + stdc_trailing_zeros_ul: + c-definition: 7.18.5 + stdc_trailing_zeros_ull: + c-definition: 7.18.5 + stdc_trailing_zeros_us: + c-definition: 7.18.5 +macros: + __STDC_ENDIAN_BIG__: + c-definition: 7.18.2.2 + __STDC_ENDIAN_LITTLE__: + c-definition: 7.18.2.2 + __STDC_ENDIAN_NATIVE__: + c-definition: 7.18.2.2 + __STDC_VERSION_STDBIT_H__: + c-definition: 7.18.1.2 + stdc_bit_ceil: + c-definition: 7.18.16.1 + stdc_bit_floor: + c-definition: 7.18.15.1 + stdc_bit_width: + c-definition: 7.18.14.1 + stdc_count_ones: + c-definition: 7.18.12.1 + stdc_count_zeros: + c-definition: 7.18.11.1 + stdc_first_leading_one: + c-definition: 7.18.8.1 + stdc_first_leading_zero: + c-definition: 7.18.7.1 + stdc_first_trailing_one: + c-definition: 7.18.10.1 + stdc_first_trailing_zero: + c-definition: 7.18.9.1 + stdc_has_single_bit: + c-definition: 7.18.13.1 + stdc_leading_ones: + c-definition: 7.18.4.1 + stdc_leading_zeros: + c-definition: 7.18.3.1 + stdc_trailing_ones: + c-definition: 7.18.6.1 + stdc_trailing_zeros: + c-definition: 7.18.5.1 + diff --git a/libc/utils/docgen/stdlib.yaml b/libc/utils/docgen/stdlib.yaml new file mode 100644 index 0000000000000..526ddefbe1ce3 --- /dev/null +++ b/libc/utils/docgen/stdlib.yaml @@ -0,0 +1,158 @@ +functions: + _Exit: + c-definition: 7.24.4.5 + in-latest-posix: '' + abort: + c-definition: 7.24.4.1 + in-latest-posix: '' + abs: + c-definition: 7.24.6.1 + in-latest-posix: '' + aligned_alloc: + c-definition: 7.24.3.1 + in-latest-posix: '' + at_quick_exit: + c-definition: 7.24.4.3 + in-latest-posix: '' + atexit: + c-definition: 7.24.4.2 + in-latest-posix: '' + atof: + c-definition: 7.24.1.1 + in-latest-posix: '' + atoi: + c-definition: 7.24.1.2 + in-latest-posix: '' + atol: + c-definition: 7.24.1.2 + in-latest-posix: '' + atoll: + c-definition: 7.24.1.2 + in-latest-posix: '' + bsearch: + c-definition: 7.24.5.1 + in-latest-posix: '' + calloc: + c-definition: 7.24.3.2 + in-latest-posix: '' + div: + c-definition: 7.24.6.2 + in-latest-posix: '' + exit: + c-definition: 7.24.4.4 + in-latest-posix: '' + free: + c-definition: 7.24.3.3 + in-latest-posix: '' + free_aligned_sized: + c-definition: 7.24.3.5 + free_sized: + c-definition: 7.24.3.4 + getenv: + c-definition: 7.24.4.6 + in-latest-posix: '' + labs: + c-definition: 7.24.6.1 + in-latest-posix: '' + ldiv: + c-definition: 7.24.6.2 + in-latest-posix: '' + llabs: + c-definition: 7.24.6.1 + in-latest-posix: '' + lldiv: + c-definition: 7.24.6.2 + in-latest-posix: '' + malloc: + c-definition: 7.24.3.6 + in-latest-posix: '' + mblen: + c-definition: 7.24.7.1 + in-latest-posix: '' + mbstowcs: + c-definition: 7.24.8.1 + in-latest-posix: '' + mbtowc: + c-definition: 7.24.7.2 + in-latest-posix: '' + memalignment: + c-definition: 7.24.9.1 + qsort: + c-definition: 7.24.5.2 + in-latest-posix: '' + quick_exit: + c-definition: 7.24.4.7 + in-latest-posix: '' + rand: + c-definition: 7.24.2.1 + in-latest-posix: '' + realloc: + c-definition: 7.24.3.7 + in-latest-posix: '' + srand: + c-definition: 7.24.2.2 + in-latest-posix: '' + strfromd: + c-definition: 7.24.1.3 + strfromd128: + c-definition: 7.24.1.4 + strfromd32: + c-definition: 7.24.1.4 + strfromd64: + c-definition: 7.24.1.4 + strfromf: + c-definition: 7.24.1.3 + strfroml: + c-definition: 7.24.1.3 + strtod: + c-definition: 7.24.1.5 + in-latest-posix: '' + strtod128: + c-definition: 7.24.1.6 + strtod32: + c-definition: 7.24.1.6 + strtod64: + c-definition: 7.24.1.6 + strtof: + c-definition: 7.24.1.5 + in-latest-posix: '' + strtol: + c-definition: 7.24.1.7 + in-latest-posix: '' + strtold: + c-definition: 7.24.1.5 + in-latest-posix: '' + strtoll: + c-definition: 7.24.1.7 + in-latest-posix: '' + strtoul: + c-definition: 7.24.1.7 + in-latest-posix: '' + strtoull: + c-definition: 7.24.1.7 + in-latest-posix: '' + system: + c-definition: 7.24.4.8 + in-latest-posix: '' + wcstombs: + c-definition: 7.24.8.2 + in-latest-posix: '' + wctomb: + c-definition: 7.24.7.3 + in-latest-posix: '' +macros: + EXIT_FAILURE: + c-definition: '7.24' + in-latest-posix: '' + EXIT_SUCCESS: + c-definition: '7.24' + in-latest-posix: '' + MB_CUR_MAX: + c-definition: '7.24' + in-latest-posix: '' + RAND_MAX: + c-definition: '7.24' + in-latest-posix: '' + __STDC_VERSION_STDLIB_H__: + c-definition: '7.24' + diff --git a/libc/utils/docgen/string.yaml b/libc/utils/docgen/string.yaml new file mode 100644 index 0000000000000..d703a8e3593e1 --- /dev/null +++ b/libc/utils/docgen/string.yaml @@ -0,0 +1,94 @@ +functions: + memccpy: + c-definition: 7.26.2.2 + in-latest-posix: '' + memchr: + c-definition: 7.26.5.2 + in-latest-posix: '' + memcmp: + c-definition: 7.26.4.1 + in-latest-posix: '' + memcpy: + c-definition: 7.26.2.1 + in-latest-posix: '' + memmove: + c-definition: 7.26.2.3 + in-latest-posix: '' + mempcpy: + c-definition: 'TODO: glibc extension' + memset: + c-definition: 7.26.6.1 + in-latest-posix: '' + memset_explicit: + c-definition: 7.26.6.2 + stpcpy: + in-latest-posix: '' + stpncpy: + in-latest-posix: '' + strcat: + c-definition: 7.26.3.1 + in-latest-posix: '' + strchr: + c-definition: 7.26.5.3 + in-latest-posix: '' + strcmp: + c-definition: 7.26.4.2 + in-latest-posix: '' + strcoll: + c-definition: 7.26.4.3 + in-latest-posix: '' + strcoll_l: + in-latest-posix: '' + strcpy: + c-definition: 7.26.2.4 + in-latest-posix: '' + strcspn: + c-definition: 7.26.5.4 + in-latest-posix: '' + strdup: + c-definition: 7.26.2.6 + in-latest-posix: '' + strerror: + c-definition: 7.26.6.3 + in-latest-posix: '' + strlen: + c-definition: 7.26.6.4 + in-latest-posix: '' + strncat: + c-definition: 7.26.3.2 + in-latest-posix: '' + strncmp: + c-definition: 7.26.4.4 + in-latest-posix: '' + strncpy: + c-definition: 7.26.2.5 + in-latest-posix: '' + strndup: + c-definition: 7.26.2.7 + in-latest-posix: '' + strpbrk: + c-definition: 7.26.5.5 + in-latest-posix: '' + strrchr: + c-definition: 7.26.5.6 + in-latest-posix: '' + strspn: + c-definition: 7.26.5.7 + in-latest-posix: '' + strstr: + c-definition: 7.26.5.8 + in-latest-posix: '' + strtok: + c-definition: 7.26.5.9 + in-latest-posix: '' + strtok_r: + in-latest-posix: '' + strxfrm: + c-definition: 7.26.4.5 + in-latest-posix: '' + strxfrm_l: + in-latest-posix: '' +macros: + __STDC_VERSION_STRING_H__: + c-definition: 7.26.1 + diff --git a/libc/utils/docgen/sys/mman.yaml b/libc/utils/docgen/sys/mman.yaml new file mode 100644 index 0000000000000..dba26cabc6621 --- /dev/null +++ b/libc/utils/docgen/sys/mman.yaml @@ -0,0 +1,77 @@ +functions: + mlock: + posix-definition: '' + mlockall: + posix-definition: '' + mmap: + posix-definition: '' + mprotect: + posix-definition: '' + msync: + posix-definition: '' + munlock: + posix-definition: '' + munlockall: + posix-definition: '' + munmap: + posix-definition: '' + posix_madvise: + posix-definition: '' + posix_mem_offset: + posix-definition: '' + posix_typed_mem_get_info: + posix-definition: '' + posix_typed_mem_open: + posix-definition: '' + shm_open: + posix-definition: '' + shm_unlink: + posix-definition: '' +macros: + MAP_ANON: + posix-definition: '' + MAP_ANONYMOUS: + posix-definition: '' + MAP_FAILED: + posix-definition: '' + MAP_FIXED: + posix-definition: '' + MAP_PRIVATE: + posix-definition: '' + MAP_SHARED: + posix-definition: '' + MCL_CURRENT: + posix-definition: '' + MCL_FUTURE: + posix-definition: '' + MS_ASYNC: + posix-definition: '' + MS_INVALIDATE: + posix-definition: '' + MS_SYNC: + posix-definition: '' + POSIX_MADV_DONTNEED: + posix-definition: '' + POSIX_MADV_NORMAL: + posix-definition: '' + POSIX_MADV_RANDOM: + posix-definition: '' + POSIX_MADV_SEQUENTIAL: + posix-definition: '' + POSIX_MADV_WILLNEED: + posix-definition: '' + POSIX_TYPED_MEM_ALLOCATE: + posix-definition: '' + POSIX_TYPED_MEM_ALLOCATE_CONTIG: + posix-definition: '' + POSIX_TYPED_MEM_MAP_ALLOCATABLE: + posix-definition: '' + PROT_EXEC: + posix-definition: '' + PROT_NONE: + posix-definition: '' + PROT_READ: + posix-definition: '' + PROT_WRITE: + posix-definition: '' + diff --git a/libc/utils/docgen/threads.json b/libc/utils/docgen/threads.json deleted file mode 100644 index 8591cbde55a49..0000000000000 --- a/libc/utils/docgen/threads.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "macros": { - "ONCE_FLAG_INIT": { - "c-definition": "7.28.1.3" - }, - "TSS_DTOR_ITERATIONS": { - "c-definition": "7.28.1.3" - } - }, - "functions": { - "call_once": { - "c-definition": "7.28.2.1" - }, - "cnd_broadcast": { - "c-definition": "7.28.3.1" - }, - "cnd_destroy": { - "c-definition": "7.28.3.2" - }, - "cnd_init": { - "c-definition": "7.28.3.3" - }, - "cnd_signal": { - "c-definition": "7.28.3.4" - }, - "cnd_timedwait": { - "c-definition": "7.28.3.5" - }, - "cnd_wait": { - "c-definition": "7.28.3.6" - }, - "mtx_destroy": { - "c-definition": "7.28.4.1" - }, - "mtx_init": { - "c-definition": "7.28.4.2" - }, - "mtx_lock": { - "c-definition": "7.28.4.3" - }, - "mtx_timedlock": { - "c-definition": "7.28.4.4" - }, - "mtx_trylock": { - "c-definition": "7.28.4.5" - }, - "mtx_unlock": { - "c-definition": "7.28.4.6" - }, - "thrd_create": { - "c-definition": "7.28.5.1" - }, - "thrd_current": { - "c-definition": "7.28.5.2" - }, - "thrd_detach": { - "c-definition": "7.28.5.3" - }, - "thrd_equal": { - "c-definition": "7.28.5.4" - }, - "thrd_exit": { - "c-definition": "7.28.5.5" - }, - "thrd_join": { - "c-definition": "7.28.5.6" - }, - "thrd_sleep": { - "c-definition": "7.28.5.7" - }, - "thrd_yield": { - "c-definition": "7.28.5.8" - }, - "tss_create": { - "c-definition": "7.28.6.1" - }, - "tss_delete": { - "c-definition": "7.28.6.2" - }, - "tss_get": { - "c-definition": "7.28.6.3" - }, - "tss_set": { - "c-definition": "7.28.6.4" - } - } -} diff --git a/libc/utils/docgen/threads.yaml b/libc/utils/docgen/threads.yaml new file mode 100644 index 0000000000000..83db0992dc45d --- /dev/null +++ b/libc/utils/docgen/threads.yaml @@ -0,0 +1,88 @@ +functions: + call_once: + c-definition: 7.28.2.1 + in-latest-posix: '' + cnd_broadcast: + c-definition: 7.28.3.1 + in-latest-posix: '' + cnd_destroy: + c-definition: 7.28.3.2 + in-latest-posix: '' + cnd_init: + c-definition: 7.28.3.3 + in-latest-posix: '' + cnd_signal: + c-definition: 7.28.3.4 + in-latest-posix: '' + cnd_timedwait: + c-definition: 7.28.3.5 + in-latest-posix: '' + cnd_wait: + c-definition: 7.28.3.6 + in-latest-posix: '' + mtx_destroy: + c-definition: 7.28.4.2 + in-latest-posix: '' + mtx_init: + c-definition: 7.28.4.3 + in-latest-posix: '' + mtx_lock: + c-definition: 7.28.4.4 + in-latest-posix: '' + mtx_timedlock: + c-definition: 7.28.4.5 + in-latest-posix: '' + mtx_trylock: + c-definition: 7.28.4.6 + in-latest-posix: '' + mtx_unlock: + c-definition: 7.28.4.7 + in-latest-posix: '' + thrd_create: + c-definition: 7.28.5.1 + in-latest-posix: '' + thrd_current: + c-definition: 7.28.5.2 + in-latest-posix: '' + thrd_detach: + c-definition: 7.28.5.3 + in-latest-posix: '' + thrd_equal: + c-definition: 7.28.5.4 + in-latest-posix: '' + thrd_exit: + c-definition: 7.28.5.5 + in-latest-posix: '' + thrd_join: + c-definition: 7.28.5.6 + in-latest-posix: '' + thrd_sleep: + c-definition: 7.28.5.7 + in-latest-posix: '' + thrd_yield: + c-definition: 7.28.5.8 + in-latest-posix: '' + tss_create: + c-definition: 7.28.6.1 + in-latest-posix: '' + tss_delete: + c-definition: 7.28.6.2 + in-latest-posix: '' + tss_get: + c-definition: 7.28.6.3 + in-latest-posix: '' + tss_set: + c-definition: 7.28.6.4 + in-latest-posix: '' +macros: + ONCE_FLAG_INIT: + c-definition: 7.28.1 + in-latest-posix: '' + TSS_DTOR_ITERATIONS: + c-definition: 7.28.1 + in-latest-posix: '' + __STDC_NO_THREADS__: + c-definition: 7.28.1 + thread_local: + in-latest-posix: '' + diff --git a/libc/utils/docgen/uchar.yaml b/libc/utils/docgen/uchar.yaml new file mode 100644 index 0000000000000..580af0f548336 --- /dev/null +++ b/libc/utils/docgen/uchar.yaml @@ -0,0 +1,21 @@ +functions: + c16rtomb: + c-definition: 7.30.2.5 + in-latest-posix: '' + c32rtomb: + c-definition: 7.30.2.7 + in-latest-posix: '' + c8rtomb: + c-definition: 7.30.2.3 + mbrtoc16: + c-definition: 7.30.2.4 + in-latest-posix: '' + mbrtoc32: + c-definition: 7.30.2.6 + in-latest-posix: '' + mbrtoc8: + c-definition: 7.30.2.2 +macros: + __STDC_VERSION_UCHAR_H__: + c-definition: 7.30.1 + diff --git a/libc/utils/docgen/wchar.yaml b/libc/utils/docgen/wchar.yaml new file mode 100644 index 0000000000000..dcc8963efdd35 --- /dev/null +++ b/libc/utils/docgen/wchar.yaml @@ -0,0 +1,131 @@ +functions: + btowc: + c-definition: 7.31.6.2.1 + fgetwc: + c-definition: 7.31.3.1 + fgetws: + c-definition: 7.31.3.2 + fputwc: + c-definition: 7.31.3.3 + fputws: + c-definition: 7.31.3.4 + fwide: + c-definition: 7.31.3.5 + fwprintf: + c-definition: 7.31.2.2 + fwscanf: + c-definition: 7.31.2.3 + getwc: + c-definition: 7.31.3.6 + getwchar: + c-definition: 7.31.3.7 + mbrlen: + c-definition: 7.31.6.4.2 + mbrtowc: + c-definition: 7.31.6.4.3 + mbsinit: + c-definition: 7.31.6.3.1 + mbsrtowcs: + c-definition: 7.31.6.5.2 + putwc: + c-definition: 7.31.3.8 + putwchar: + c-definition: 7.31.3.9 + swprintf: + c-definition: 7.31.2.4 + swscanf: + c-definition: 7.31.2.5 + ungetwc: + c-definition: 7.31.3.10 + vfwprintf: + c-definition: 7.31.2.6 + vfwscanf: + c-definition: 7.31.2.7 + vswprintf: + c-definition: 7.31.2.8 + vswscanf: + c-definition: 7.31.2.9 + vwprintf: + c-definition: 7.31.2.10 + vwscanf: + c-definition: 7.31.2.11 + wcrtomb: + c-definition: 7.31.6.4.4 + wcscat: + c-definition: 7.31.4.4.1 + wcschr: + c-definition: 7.31.4.6.2 + wcscmp: + c-definition: 7.31.4.5.2 + wcscoll: + c-definition: 7.31.4.5.3 + wcscpy: + c-definition: 7.31.4.3.1 + wcscspn: + c-definition: 7.31.4.6.3 + wcsftime: + c-definition: 7.31.5.1 + wcslen: + c-definition: 7.31.4.7.1 + wcsncat: + c-definition: 7.31.4.4.2 + wcsncmp: + c-definition: 7.31.4.5.4 + wcsncpy: + c-definition: 7.31.4.3.2 + wcspbrk: + c-definition: 7.31.4.6.4 + wcsrchr: + c-definition: 7.31.4.6.5 + wcsrtombs: + c-definition: 7.31.6.5.3 + wcsspn: + c-definition: 7.31.4.6.6 + wcsstr: + c-definition: 7.31.4.6.7 + wcstod: + c-definition: 7.31.4.2.2 + wcstod128: + c-definition: 7.31.4.2.3 + wcstod32: + c-definition: 7.31.4.2.3 + wcstod64: + c-definition: 7.31.4.2.3 + wcstof: + c-definition: 7.31.4.2.2 + wcstok: + c-definition: 7.31.4.6.8 + wcstol: + c-definition: 7.31.4.2.4 + wcstold: + c-definition: 7.31.4.2.2 + wcstoll: + c-definition: 7.31.4.2.4 + wcstoul: + c-definition: 7.31.4.2.4 + wcstoull: + c-definition: 7.31.4.2.4 + wcsxfrm: + c-definition: 7.31.4.5.5 + wctob: + c-definition: 7.31.6.2.2 + wmemchr: + c-definition: 7.31.4.6.9 + wmemcmp: + c-definition: 7.31.4.5.6 + wmemcpy: + c-definition: 7.31.4.3.3 + wmemmove: + c-definition: 7.31.4.3.4 + wmemset: + c-definition: 7.31.4.7.2 + wprintf: + c-definition: 7.31.2.12 + wscanf: + c-definition: 7.31.2.13 +macros: + WEOF: + c-definition: 7.31.1 + __STDC_VERSION_WCHAR_H__: + c-definition: 7.31.1 + diff --git a/libc/utils/docgen/wctype.yaml b/libc/utils/docgen/wctype.yaml new file mode 100644 index 0000000000000..8675cbe500da3 --- /dev/null +++ b/libc/utils/docgen/wctype.yaml @@ -0,0 +1,36 @@ +functions: + iswalnum: + c-definition: 7.32.2.1.1 + iswalpha: + c-definition: 7.32.2.1.2 + iswblank: + c-definition: 7.32.2.1.4 + iswctype: + c-definition: 7.32.2.2.1 + iswdigit: + c-definition: 7.32.2.1.5 + iswgraph: + c-definition: 7.32.2.1.6 + iswlower: + c-definition: 7.32.2.1.7 + iswprint: + c-definition: 7.32.2.1.8 + iswpunct: + c-definition: 7.32.2.1.9 + iswspace: + c-definition: 7.32.2.1.10 + iswupper: + c-definition: 7.32.2.1.11 + iswxdigit: + c-definition: 7.32.2.1.12 + towctrans: + c-definition: 7.32.3.2.1 + towlower: + c-definition: 7.32.3.1.1 + towupper: + c-definition: 7.32.3.1.2 + wctrans: + c-definition: 7.32.3.2.2 + wctype: + c-definition: 7.32.2.2.2 + diff --git a/libc/utils/gpu/loader/Loader.h b/libc/utils/gpu/loader/Loader.h index 0d683832855e9..8e86f63969326 100644 --- a/libc/utils/gpu/loader/Loader.h +++ b/libc/utils/gpu/loader/Loader.h @@ -113,7 +113,7 @@ inline uint32_t handle_server(rpc::Server &server, uint32_t index, return 0; index = port->get_index() + 1; - int status = rpc::SUCCESS; + int status = rpc::RPC_SUCCESS; switch (port->get_opcode()) { case RPC_TEST_INCREMENT: { port->recv_and_send([](rpc::Buffer *buffer, uint32_t) { @@ -186,7 +186,7 @@ inline uint32_t handle_server(rpc::Server &server, uint32_t index, } // Handle all of the `libc` specific opcodes. - if (status != rpc::SUCCESS) + if (status != rpc::RPC_SUCCESS) handle_error("Error handling RPC server"); port->close(); diff --git a/libc/utils/gpu/server/rpc_server.cpp b/libc/utils/gpu/server/rpc_server.cpp index f724c5c82c422..1faee531fa20d 100644 --- a/libc/utils/gpu/server/rpc_server.cpp +++ b/libc/utils/gpu/server/rpc_server.cpp @@ -437,10 +437,10 @@ rpc::Status handle_port_impl(rpc::Server::Port &port) { break; } default: - return rpc::UNHANDLED_OPCODE; + return rpc::RPC_UNHANDLED_OPCODE; } - return rpc::SUCCESS; + return rpc::RPC_SUCCESS; } namespace rpc { @@ -455,7 +455,7 @@ rpc::Status handle_libc_opcodes(rpc::Server::Port &port, uint32_t num_lanes) { case 64: return handle_port_impl<64>(port); default: - return rpc::ERROR; + return rpc::RPC_ERROR; } } } // namespace rpc diff --git a/libclc/clc/include/clc/clcmacro.h b/libclc/clc/include/clc/clcmacro.h index 244239284ecab..c6583749eca66 100644 --- a/libclc/clc/include/clc/clcmacro.h +++ b/libclc/clc/include/clc/clcmacro.h @@ -191,7 +191,21 @@ #define _CLC_DEFINE_UNARY_BUILTIN(RET_TYPE, FUNCTION, BUILTIN, ARG1_TYPE) \ _CLC_DEF _CLC_OVERLOAD RET_TYPE FUNCTION(ARG1_TYPE x) { return BUILTIN(x); } \ - _CLC_UNARY_VECTORIZE(_CLC_OVERLOAD _CLC_DEF, RET_TYPE, FUNCTION, ARG1_TYPE) + _CLC_DEF _CLC_OVERLOAD RET_TYPE##2 FUNCTION(ARG1_TYPE##2 x) { \ + return BUILTIN(x); \ + } \ + _CLC_DEF _CLC_OVERLOAD RET_TYPE##3 FUNCTION(ARG1_TYPE##3 x) { \ + return BUILTIN(x); \ + } \ + _CLC_DEF _CLC_OVERLOAD RET_TYPE##4 FUNCTION(ARG1_TYPE##4 x) { \ + return BUILTIN(x); \ + } \ + _CLC_DEF _CLC_OVERLOAD RET_TYPE##8 FUNCTION(ARG1_TYPE##8 x) { \ + return BUILTIN(x); \ + } \ + _CLC_DEF _CLC_OVERLOAD RET_TYPE##16 FUNCTION(ARG1_TYPE##16 x) { \ + return BUILTIN(x); \ + } #ifdef cl_khr_fp16 diff --git a/libclc/clc/include/clc/math/clc_ceil.h b/libclc/clc/include/clc/math/clc_ceil.h index 66590687c3422..20adc6d81d863 100644 --- a/libclc/clc/include/clc/math/clc_ceil.h +++ b/libclc/clc/include/clc/math/clc_ceil.h @@ -1,19 +1,12 @@ #ifndef __CLC_MATH_CLC_CEIL_H__ #define __CLC_MATH_CLC_CEIL_H__ -#if defined(CLC_CLSPV) || defined(CLC_SPIRV) -// clspv and spir-v targets provide their own OpenCL-compatible ceil -#define __clc_ceil ceil -#else - -// Map the function to an LLVM intrinsic +#define __CLC_BODY #define __CLC_FUNCTION __clc_ceil -#define __CLC_INTRINSIC "llvm.ceil" -#include -#undef __CLC_INTRINSIC -#undef __CLC_FUNCTION +#include -#endif +#undef __CLC_BODY +#undef __CLC_FUNCTION #endif // __CLC_MATH_CLC_CEIL_H__ diff --git a/libclc/clc/include/clc/math/clc_fabs.h b/libclc/clc/include/clc/math/clc_fabs.h index 93367b5731371..911d34f78c7d2 100644 --- a/libclc/clc/include/clc/math/clc_fabs.h +++ b/libclc/clc/include/clc/math/clc_fabs.h @@ -1,19 +1,12 @@ #ifndef __CLC_MATH_CLC_FABS_H__ #define __CLC_MATH_CLC_FABS_H__ -#if defined(CLC_CLSPV) || defined(CLC_SPIRV) -// clspv and spir-v targets provide their own OpenCL-compatible fabs -#define __clc_fabs fabs -#else - -// Map the function to an LLVM intrinsic +#define __CLC_BODY #define __CLC_FUNCTION __clc_fabs -#define __CLC_INTRINSIC "llvm.fabs" -#include -#undef __CLC_INTRINSIC -#undef __CLC_FUNCTION +#include -#endif +#undef __CLC_BODY +#undef __CLC_FUNCTION #endif // __CLC_MATH_CLC_FABS_H__ diff --git a/libclc/clc/include/clc/math/clc_floor.h b/libclc/clc/include/clc/math/clc_floor.h index 9919872ec633c..c311cc0edae15 100644 --- a/libclc/clc/include/clc/math/clc_floor.h +++ b/libclc/clc/include/clc/math/clc_floor.h @@ -1,19 +1,12 @@ #ifndef __CLC_MATH_CLC_FLOOR_H__ #define __CLC_MATH_CLC_FLOOR_H__ -#if defined(CLC_CLSPV) || defined(CLC_SPIRV) -// clspv and spir-v targets provide their own OpenCL-compatible floor -#define __clc_floor floor -#else - -// Map the function to an LLVM intrinsic +#define __CLC_BODY #define __CLC_FUNCTION __clc_floor -#define __CLC_INTRINSIC "llvm.floor" -#include -#undef __CLC_INTRINSIC -#undef __CLC_FUNCTION +#include -#endif +#undef __CLC_BODY +#undef __CLC_FUNCTION #endif // __CLC_MATH_CLC_FLOOR_H__ diff --git a/libclc/clc/include/clc/math/clc_rint.h b/libclc/clc/include/clc/math/clc_rint.h index 3761407ad326d..6faeed0b5696e 100644 --- a/libclc/clc/include/clc/math/clc_rint.h +++ b/libclc/clc/include/clc/math/clc_rint.h @@ -1,19 +1,12 @@ #ifndef __CLC_MATH_CLC_RINT_H__ #define __CLC_MATH_CLC_RINT_H__ -#if defined(CLC_CLSPV) || defined(CLC_SPIRV) -// clspv and spir-v targets provide their own OpenCL-compatible rint -#define __clc_rint rint -#else - -// Map the function to an LLVM intrinsic +#define __CLC_BODY #define __CLC_FUNCTION __clc_rint -#define __CLC_INTRINSIC "llvm.rint" -#include -#undef __CLC_INTRINSIC -#undef __CLC_FUNCTION +#include -#endif +#undef __CLC_BODY +#undef __CLC_FUNCTION #endif // __CLC_MATH_CLC_RINT_H__ diff --git a/libclc/clc/include/clc/math/clc_trunc.h b/libclc/clc/include/clc/math/clc_trunc.h index c78c8899d8523..acfc9d5db4811 100644 --- a/libclc/clc/include/clc/math/clc_trunc.h +++ b/libclc/clc/include/clc/math/clc_trunc.h @@ -1,19 +1,12 @@ #ifndef __CLC_MATH_CLC_TRUNC_H__ #define __CLC_MATH_CLC_TRUNC_H__ -#if defined(CLC_CLSPV) || defined(CLC_SPIRV) -// clspv and spir-v targets provide their own OpenCL-compatible trunc -#define __clc_trunc trunc -#else - -// Map the function to an LLVM intrinsic +#define __CLC_BODY #define __CLC_FUNCTION __clc_trunc -#define __CLC_INTRINSIC "llvm.trunc" -#include -#undef __CLC_INTRINSIC -#undef __CLC_FUNCTION +#include -#endif +#undef __CLC_BODY +#undef __CLC_FUNCTION #endif // __CLC_MATH_CLC_TRUNC_H__ diff --git a/libclc/generic/lib/math/unary_builtin.inc b/libclc/clc/include/clc/math/unary_builtin.inc similarity index 100% rename from libclc/generic/lib/math/unary_builtin.inc rename to libclc/clc/include/clc/math/unary_builtin.inc diff --git a/libclc/clc/lib/clspv/SOURCES b/libclc/clc/lib/clspv/SOURCES index 75a3130357c34..393e8d773cda0 100644 --- a/libclc/clc/lib/clspv/SOURCES +++ b/libclc/clc/lib/clspv/SOURCES @@ -1 +1,5 @@ -dummy.cl +../generic/math/clc_ceil.cl +../generic/math/clc_fabs.cl +../generic/math/clc_floor.cl +../generic/math/clc_rint.cl +../generic/math/clc_trunc.cl diff --git a/libclc/clc/lib/clspv/dummy.cl b/libclc/clc/lib/clspv/dummy.cl deleted file mode 100644 index fab17ac780e37..0000000000000 --- a/libclc/clc/lib/clspv/dummy.cl +++ /dev/null @@ -1 +0,0 @@ -// Empty file diff --git a/libclc/clc/lib/generic/SOURCES b/libclc/clc/lib/generic/SOURCES index d7ffaaf6dc3f4..3916ea15f5c45 100644 --- a/libclc/clc/lib/generic/SOURCES +++ b/libclc/clc/lib/generic/SOURCES @@ -1,6 +1,11 @@ geometric/clc_dot.cl integer/clc_abs.cl integer/clc_abs_diff.cl +math/clc_ceil.cl +math/clc_fabs.cl +math/clc_floor.cl +math/clc_rint.cl +math/clc_trunc.cl relational/clc_all.cl relational/clc_any.cl relational/clc_bitselect.cl diff --git a/libclc/clc/lib/generic/math/clc_ceil.cl b/libclc/clc/lib/generic/math/clc_ceil.cl new file mode 100644 index 0000000000000..c712e5fd024d9 --- /dev/null +++ b/libclc/clc/lib/generic/math/clc_ceil.cl @@ -0,0 +1,6 @@ +#include + +#undef __CLC_FUNCTION +#define __CLC_FUNCTION __clc_ceil +#define __CLC_BUILTIN __builtin_elementwise_ceil +#include diff --git a/libclc/clc/lib/generic/math/clc_fabs.cl b/libclc/clc/lib/generic/math/clc_fabs.cl new file mode 100644 index 0000000000000..23ff3a7a187e1 --- /dev/null +++ b/libclc/clc/lib/generic/math/clc_fabs.cl @@ -0,0 +1,6 @@ +#include + +#undef __CLC_FUNCTION +#define __CLC_FUNCTION __clc_fabs +#define __CLC_BUILTIN __builtin_elementwise_abs +#include diff --git a/libclc/clc/lib/generic/math/clc_floor.cl b/libclc/clc/lib/generic/math/clc_floor.cl new file mode 100644 index 0000000000000..98345c768f227 --- /dev/null +++ b/libclc/clc/lib/generic/math/clc_floor.cl @@ -0,0 +1,6 @@ +#include + +#undef __CLC_FUNCTION +#define __CLC_FUNCTION __clc_floor +#define __CLC_BUILTIN __builtin_elementwise_floor +#include diff --git a/libclc/clc/lib/generic/math/clc_rint.cl b/libclc/clc/lib/generic/math/clc_rint.cl new file mode 100644 index 0000000000000..28ad321a7b4f6 --- /dev/null +++ b/libclc/clc/lib/generic/math/clc_rint.cl @@ -0,0 +1,6 @@ +#include + +#undef __CLC_FUNCTION +#define __CLC_FUNCTION __clc_rint +#define __CLC_BUILTIN __builtin_elementwise_rint +#include diff --git a/libclc/clc/lib/generic/math/clc_trunc.cl b/libclc/clc/lib/generic/math/clc_trunc.cl new file mode 100644 index 0000000000000..e62ae062e0502 --- /dev/null +++ b/libclc/clc/lib/generic/math/clc_trunc.cl @@ -0,0 +1,6 @@ +#include + +#undef __CLC_FUNCTION +#define __CLC_FUNCTION __clc_trunc +#define __CLC_BUILTIN __builtin_elementwise_trunc +#include diff --git a/libclc/clc/lib/spirv/SOURCES b/libclc/clc/lib/spirv/SOURCES index d8effd19613c8..3b29fa0a91624 100644 --- a/libclc/clc/lib/spirv/SOURCES +++ b/libclc/clc/lib/spirv/SOURCES @@ -1,2 +1,6 @@ ../generic/geometric/clc_dot.cl - +../generic/math/clc_ceil.cl +../generic/math/clc_fabs.cl +../generic/math/clc_floor.cl +../generic/math/clc_rint.cl +../generic/math/clc_trunc.cl diff --git a/libclc/clc/lib/spirv64/SOURCES b/libclc/clc/lib/spirv64/SOURCES index 9200810ace38e..3b29fa0a91624 100644 --- a/libclc/clc/lib/spirv64/SOURCES +++ b/libclc/clc/lib/spirv64/SOURCES @@ -1 +1,6 @@ ../generic/geometric/clc_dot.cl +../generic/math/clc_ceil.cl +../generic/math/clc_fabs.cl +../generic/math/clc_floor.cl +../generic/math/clc_rint.cl +../generic/math/clc_trunc.cl diff --git a/libclc/generic/lib/math/ceil.cl b/libclc/generic/lib/math/ceil.cl index e02789e694e06..8df864a06314d 100644 --- a/libclc/generic/lib/math/ceil.cl +++ b/libclc/generic/lib/math/ceil.cl @@ -4,4 +4,4 @@ #undef __CLC_FUNCTION #define __CLC_FUNCTION ceil -#include "unary_builtin.inc" +#include diff --git a/libclc/generic/lib/math/fabs.cl b/libclc/generic/lib/math/fabs.cl index 9644369d4a095..55701cb36a951 100644 --- a/libclc/generic/lib/math/fabs.cl +++ b/libclc/generic/lib/math/fabs.cl @@ -4,4 +4,4 @@ #undef __CLC_FUNCTION #define __CLC_FUNCTION fabs -#include "unary_builtin.inc" +#include diff --git a/libclc/generic/lib/math/floor.cl b/libclc/generic/lib/math/floor.cl index f5c36b73862a4..0854fa7efc458 100644 --- a/libclc/generic/lib/math/floor.cl +++ b/libclc/generic/lib/math/floor.cl @@ -4,4 +4,4 @@ #undef __CLC_FUNCTION #define __CLC_FUNCTION floor -#include "unary_builtin.inc" +#include diff --git a/libclc/generic/lib/math/rint.cl b/libclc/generic/lib/math/rint.cl index 185bbbbf8c91d..ecf7d5c1e6dde 100644 --- a/libclc/generic/lib/math/rint.cl +++ b/libclc/generic/lib/math/rint.cl @@ -3,4 +3,4 @@ #undef __CLC_FUNCTION #define __CLC_FUNCTION rint -#include "unary_builtin.inc" +#include diff --git a/libclc/generic/lib/math/round.cl b/libclc/generic/lib/math/round.cl index 285328aaa5d56..6344051820c79 100644 --- a/libclc/generic/lib/math/round.cl +++ b/libclc/generic/lib/math/round.cl @@ -7,4 +7,4 @@ #undef __CLC_FUNCTION #define __CLC_FUNCTION round -#include "unary_builtin.inc" +#include diff --git a/libclc/generic/lib/math/sqrt.cl b/libclc/generic/lib/math/sqrt.cl index 8df25dd45adb6..a9192a9493d17 100644 --- a/libclc/generic/lib/math/sqrt.cl +++ b/libclc/generic/lib/math/sqrt.cl @@ -24,4 +24,4 @@ #include "math/clc_sqrt.h" #define __CLC_FUNCTION sqrt -#include "unary_builtin.inc" +#include diff --git a/libclc/generic/lib/math/trunc.cl b/libclc/generic/lib/math/trunc.cl index 00c2a4a80015f..1d5f04a323054 100644 --- a/libclc/generic/lib/math/trunc.cl +++ b/libclc/generic/lib/math/trunc.cl @@ -3,4 +3,4 @@ #undef __CLC_FUNCTION #define __CLC_FUNCTION trunc -#include "unary_builtin.inc" +#include diff --git a/libcxx/Maintainers.md b/libcxx/Maintainers.md new file mode 100644 index 0000000000000..2630ed9001119 --- /dev/null +++ b/libcxx/Maintainers.md @@ -0,0 +1,10 @@ +# libc++ Maintainers + +This file is a list of the +[maintainers](https://llvm.org/docs/DeveloperPolicy.html#maintainers) for +libc++. + +# Lead maintainer + +Louis Dionne \ +ldionne.2@gmail.com (email), [ldionne](https://github.com/ldionne) (GitHub) \ No newline at end of file diff --git a/libcxx/docs/CodingGuidelines.rst b/libcxx/docs/CodingGuidelines.rst index 4d3dd12e56bf1..1bb62072e886d 100644 --- a/libcxx/docs/CodingGuidelines.rst +++ b/libcxx/docs/CodingGuidelines.rst @@ -168,3 +168,19 @@ have a recommended practice where to put them, so libc++ applies it whenever it Applications of ``[[nodiscard]]`` are code like any other code, so we aim to test them on public interfaces. This can be done with a ``.verify.cpp`` test. Many examples are available. Just look for tests with the suffix ``.nodiscard.verify.cpp``. + +Don't use public API names for symbols on the ABI boundary +========================================================== + +Most functions in libc++ are defined in headers either as templates or as ``inline`` functions. However, we sometimes +need or want to define functions in the built library. Symbols that are declared in the headers and defined in the +built library become part of the ABI of libc++, which must be preserved for backwards compatibility. This means that +we can't easily remove or rename such symbols except in special cases. + +When adding a symbol to the built library, make sure not to use a public name directly. Instead, define a +``_LIBCPP_HIDE_FROM_ABI`` function in the headers with the public name and have it call a private function in the built +library. This approach makes it easier to make changes to libc++ like move something from the built library to the +headers (which is sometimes required for ``constexpr`` support). + +When defining a function at the ABI boundary, it can also be useful to consider which attributes (like ``[[gnu::pure]]`` +and ``[[clang::noescape]]``) can be added to the function to improve the compiler's ability to optimize. diff --git a/libcxx/docs/ReleaseNotes/20.rst b/libcxx/docs/ReleaseNotes/20.rst index a72fd2d5db9e2..c8a07fb8b7334 100644 --- a/libcxx/docs/ReleaseNotes/20.rst +++ b/libcxx/docs/ReleaseNotes/20.rst @@ -152,6 +152,9 @@ ABI Affecting Changes - When using the MSVC ABI, this change results in some classes having a completely different memory layout, so this is a genuine ABI break. However, the library does not currently guarantee ABI stability on MSVC platforms. +- The localization support base API has been reimplemented, leading to different functions being exported from the + libc++ built library on Windows and Windows-like platforms. + Build System Changes -------------------- diff --git a/libcxx/docs/TestingLibcxx.rst b/libcxx/docs/TestingLibcxx.rst index 6d2c954489f62..cf092fabd046f 100644 --- a/libcxx/docs/TestingLibcxx.rst +++ b/libcxx/docs/TestingLibcxx.rst @@ -452,12 +452,7 @@ when running the benchmarks. For example, .. code-block:: bash - $ libcxx/utils/libcxx-lit -sv libcxx/test/benchmarks/string.bench.cpp --param optimization=speed - -If you want to see where a benchmark is located (e.g. you want to store the executable -for subsequent analysis), you can print that information by passing ``--show-all`` to -``lit``. That will print the command-lines being executed, which includes the location -of the executable created for that benchmark. + $ libcxx/utils/libcxx-lit libcxx/test/benchmarks/string.bench.cpp --show-all --param optimization=speed Note that benchmarks are only dry-run when run via the ``check-cxx`` target since we only want to make sure they don't rot. Do not rely on the results of benchmarks diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 2bb6d263340d3..ba392e5883ff3 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -212,11 +212,13 @@ set(files __atomic/atomic_sync.h __atomic/check_memory_order.h __atomic/contention_t.h - __atomic/cxx_atomic_impl.h __atomic/fence.h __atomic/is_always_lock_free.h __atomic/kill_dependency.h __atomic/memory_order.h + __atomic/support.h + __atomic/support/c11.h + __atomic/support/gcc.h __atomic/to_gcc_order.h __bit/bit_cast.h __bit/bit_ceil.h @@ -358,6 +360,7 @@ set(files __filesystem/space_info.h __filesystem/u8path.h __flat_map/flat_map.h + __flat_map/key_value_iterator.h __flat_map/sorted_unique.h __format/buffer.h __format/concepts.h @@ -500,12 +503,12 @@ set(files __locale_dir/locale_base_api/ibm.h __locale_dir/locale_base_api/musl.h __locale_dir/locale_base_api/openbsd.h - __locale_dir/locale_base_api/win32.h __locale_dir/locale_guard.h __locale_dir/pad_and_output.h __locale_dir/support/apple.h __locale_dir/support/bsd_like.h __locale_dir/support/freebsd.h + __locale_dir/support/windows.h __math/abs.h __math/copysign.h __math/error_functions.h @@ -578,6 +581,16 @@ set(files __mutex/once_flag.h __mutex/tag_types.h __mutex/unique_lock.h + __new/align_val_t.h + __new/allocate.h + __new/destroying_delete_t.h + __new/exceptions.h + __new/global_new_delete.h + __new/interference_size.h + __new/launder.h + __new/new_handler.h + __new/nothrow_t.h + __new/placement_new_delete.h __node_handle __numeric/accumulate.h __numeric/adjacent_difference.h diff --git a/libcxx/include/__atomic/atomic.h b/libcxx/include/__atomic/atomic.h index d83719c8733d7..8029b52770d26 100644 --- a/libcxx/include/__atomic/atomic.h +++ b/libcxx/include/__atomic/atomic.h @@ -11,9 +11,9 @@ #include <__atomic/atomic_sync.h> #include <__atomic/check_memory_order.h> -#include <__atomic/cxx_atomic_impl.h> #include <__atomic/is_always_lock_free.h> #include <__atomic/memory_order.h> +#include <__atomic/support.h> #include <__config> #include <__cstddef/ptrdiff_t.h> #include <__memory/addressof.h> diff --git a/libcxx/include/__atomic/atomic_flag.h b/libcxx/include/__atomic/atomic_flag.h index abebfc112cb8e..5cc6fb0c55d09 100644 --- a/libcxx/include/__atomic/atomic_flag.h +++ b/libcxx/include/__atomic/atomic_flag.h @@ -11,8 +11,8 @@ #include <__atomic/atomic_sync.h> #include <__atomic/contention_t.h> -#include <__atomic/cxx_atomic_impl.h> #include <__atomic/memory_order.h> +#include <__atomic/support.h> #include <__chrono/duration.h> #include <__config> #include <__memory/addressof.h> diff --git a/libcxx/include/__atomic/atomic_sync.h b/libcxx/include/__atomic/atomic_sync.h index a699b60d13184..153001e7b62e3 100644 --- a/libcxx/include/__atomic/atomic_sync.h +++ b/libcxx/include/__atomic/atomic_sync.h @@ -10,7 +10,6 @@ #define _LIBCPP___ATOMIC_ATOMIC_SYNC_H #include <__atomic/contention_t.h> -#include <__atomic/cxx_atomic_impl.h> #include <__atomic/memory_order.h> #include <__atomic/to_gcc_order.h> #include <__chrono/duration.h> diff --git a/libcxx/include/__atomic/contention_t.h b/libcxx/include/__atomic/contention_t.h index 65890f338ce99..6f2a073bc1a8e 100644 --- a/libcxx/include/__atomic/contention_t.h +++ b/libcxx/include/__atomic/contention_t.h @@ -9,7 +9,7 @@ #ifndef _LIBCPP___ATOMIC_CONTENTION_T_H #define _LIBCPP___ATOMIC_CONTENTION_T_H -#include <__atomic/cxx_atomic_impl.h> +#include <__atomic/support.h> #include <__config> #include diff --git a/libcxx/include/__atomic/fence.h b/libcxx/include/__atomic/fence.h index 8c27ea54d62dd..0a63cedddb3f9 100644 --- a/libcxx/include/__atomic/fence.h +++ b/libcxx/include/__atomic/fence.h @@ -9,8 +9,8 @@ #ifndef _LIBCPP___ATOMIC_FENCE_H #define _LIBCPP___ATOMIC_FENCE_H -#include <__atomic/cxx_atomic_impl.h> #include <__atomic/memory_order.h> +#include <__atomic/support.h> #include <__config> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) diff --git a/libcxx/include/__atomic/support.h b/libcxx/include/__atomic/support.h new file mode 100644 index 0000000000000..4b555ab483ca0 --- /dev/null +++ b/libcxx/include/__atomic/support.h @@ -0,0 +1,124 @@ +//===----------------------------------------------------------------------===// +// +// 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 _LIBCPP___ATOMIC_SUPPORT_H +#define _LIBCPP___ATOMIC_SUPPORT_H + +#include <__config> +#include <__type_traits/is_trivially_copyable.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// +// This file implements base support for atomics on the platform. +// +// The following operations and types must be implemented (where _Atmc +// is __cxx_atomic_base_impl for readability): +// +// clang-format off +// +// template +// struct __cxx_atomic_base_impl; +// +// #define __cxx_atomic_is_lock_free(__size) +// +// void __cxx_atomic_thread_fence(memory_order __order) noexcept; +// void __cxx_atomic_signal_fence(memory_order __order) noexcept; +// +// template +// void __cxx_atomic_init(_Atmc<_Tp> volatile* __a, _Tp __val) noexcept; +// template +// void __cxx_atomic_init(_Atmc<_Tp>* __a, _Tp __val) noexcept; +// +// template +// void __cxx_atomic_store(_Atmc<_Tp> volatile* __a, _Tp __val, memory_order __order) noexcept; +// template +// void __cxx_atomic_store(_Atmc<_Tp>* __a, _Tp __val, memory_order __order) noexcept; +// +// template +// _Tp __cxx_atomic_load(_Atmc<_Tp> const volatile* __a, memory_order __order) noexcept; +// template +// _Tp __cxx_atomic_load(_Atmc<_Tp> const* __a, memory_order __order) noexcept; +// +// template +// void __cxx_atomic_load_inplace(_Atmc<_Tp> const volatile* __a, _Tp* __dst, memory_order __order) noexcept; +// template +// void __cxx_atomic_load_inplace(_Atmc<_Tp> const* __a, _Tp* __dst, memory_order __order) noexcept; +// +// template +// _Tp __cxx_atomic_exchange(_Atmc<_Tp> volatile* __a, _Tp __value, memory_order __order) noexcept; +// template +// _Tp __cxx_atomic_exchange(_Atmc<_Tp>* __a, _Tp __value, memory_order __order) noexcept; +// +// template +// bool __cxx_atomic_compare_exchange_strong(_Atmc<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) noexcept; +// template +// bool __cxx_atomic_compare_exchange_strong(_Atmc<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) noexcept; +// +// template +// bool __cxx_atomic_compare_exchange_weak(_Atmc<_Tp> volatile* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) noexcept; +// template +// bool __cxx_atomic_compare_exchange_weak(_Atmc<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) noexcept; +// +// template +// _Tp __cxx_atomic_fetch_add(_Atmc<_Tp> volatile* __a, _Tp __delta, memory_order __order) noexcept; +// template +// _Tp __cxx_atomic_fetch_add(_Atmc<_Tp>* __a, _Tp __delta, memory_order __order) noexcept; +// +// template +// _Tp* __cxx_atomic_fetch_add(_Atmc<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) noexcept; +// template +// _Tp* __cxx_atomic_fetch_add(_Atmc<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) noexcept; +// +// template +// _Tp __cxx_atomic_fetch_sub(_Atmc<_Tp> volatile* __a, _Tp __delta, memory_order __order) noexcept; +// template +// _Tp __cxx_atomic_fetch_sub(_Atmc<_Tp>* __a, _Tp __delta, memory_order __order) noexcept; +// template +// _Tp* __cxx_atomic_fetch_sub(_Atmc<_Tp*> volatile* __a, ptrdiff_t __delta, memory_order __order) noexcept; +// template +// _Tp* __cxx_atomic_fetch_sub(_Atmc<_Tp*>* __a, ptrdiff_t __delta, memory_order __order) noexcept; +// +// template +// _Tp __cxx_atomic_fetch_and(_Atmc<_Tp> volatile* __a, _Tp __pattern, memory_order __order) noexcept; +// template +// _Tp __cxx_atomic_fetch_and(_Atmc<_Tp>* __a, _Tp __pattern, memory_order __order) noexcept; +// +// template +// _Tp __cxx_atomic_fetch_or(_Atmc<_Tp> volatile* __a, _Tp __pattern, memory_order __order) noexcept; +// template +// _Tp __cxx_atomic_fetch_or(_Atmc<_Tp>* __a, _Tp __pattern, memory_order __order) noexcept; +// template +// _Tp __cxx_atomic_fetch_xor(_Atmc<_Tp> volatile* __a, _Tp __pattern, memory_order __order) noexcept; +// template +// _Tp __cxx_atomic_fetch_xor(_Atmc<_Tp>* __a, _Tp __pattern, memory_order __order) noexcept; +// +// clang-format on +// + +#if _LIBCPP_HAS_GCC_ATOMIC_IMP +# include <__atomic/support/gcc.h> +#elif _LIBCPP_HAS_C_ATOMIC_IMP +# include <__atomic/support/c11.h> +#endif + +_LIBCPP_BEGIN_NAMESPACE_STD + +template > +struct __cxx_atomic_impl : public _Base { + static_assert(is_trivially_copyable<_Tp>::value, "std::atomic requires that 'T' be a trivially copyable type"); + + _LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default; + _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT : _Base(__value) {} +}; + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ATOMIC_SUPPORT_H diff --git a/libcxx/include/__atomic/cxx_atomic_impl.h b/libcxx/include/__atomic/support/c11.h similarity index 52% rename from libcxx/include/__atomic/cxx_atomic_impl.h rename to libcxx/include/__atomic/support/c11.h index acffb0fa8f5d9..177a075be4073 100644 --- a/libcxx/include/__atomic/cxx_atomic_impl.h +++ b/libcxx/include/__atomic/support/c11.h @@ -6,276 +6,39 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H -#define _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H +#ifndef _LIBCPP___ATOMIC_SUPPORT_C11_H +#define _LIBCPP___ATOMIC_SUPPORT_C11_H #include <__atomic/memory_order.h> -#include <__atomic/to_gcc_order.h> #include <__config> #include <__cstddef/ptrdiff_t.h> #include <__memory/addressof.h> -#include <__type_traits/enable_if.h> -#include <__type_traits/is_assignable.h> -#include <__type_traits/is_trivially_copyable.h> #include <__type_traits/remove_const.h> #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header #endif -_LIBCPP_BEGIN_NAMESPACE_STD - -#if _LIBCPP_HAS_GCC_ATOMIC_IMP - -// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because -// the default operator= in an object is not volatile, a byte-by-byte copy -// is required. -template ::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) { - __a_value = __val; -} -template ::value, int> = 0> -_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) { - volatile char* __to = reinterpret_cast(std::addressof(__a_value)); - volatile char* __end = __to + sizeof(_Tp); - volatile const char* __from = reinterpret_cast(std::addressof(__val)); - while (__to != __end) - *__to++ = *__from++; -} - -template -struct __cxx_atomic_base_impl { - _LIBCPP_HIDE_FROM_ABI -# ifndef _LIBCPP_CXX03_LANG - __cxx_atomic_base_impl() _NOEXCEPT = default; -# else - __cxx_atomic_base_impl() _NOEXCEPT : __a_value() { - } -# endif // _LIBCPP_CXX03_LANG - _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT : __a_value(value) {} - _Tp __a_value; -}; - -template -_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { - __cxx_atomic_assign_volatile(__a->__a_value, __val); -} - -template -_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { - __a->__a_value = __val; -} - -_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) { - __atomic_thread_fence(__to_gcc_order(__order)); -} - -_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) { - __atomic_signal_fence(__to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI void -__cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) { - __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) { - __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { - _Tp __ret; - __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order)); - return __ret; -} - -template -_LIBCPP_HIDE_FROM_ABI void -__cxx_atomic_load_inplace(const volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, memory_order __order) { - __atomic_load(std::addressof(__a->__a_value), __dst, __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI void -__cxx_atomic_load_inplace(const __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, memory_order __order) { - __atomic_load(std::addressof(__a->__a_value), __dst, __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { - _Tp __ret; - __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order)); - return __ret; -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp -__cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) { - _Tp __ret; - __atomic_exchange( - std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order)); - return __ret; -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) { - _Tp __ret; - __atomic_exchange( - std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order)); - return __ret; -} - -template -_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( - volatile __cxx_atomic_base_impl<_Tp>* __a, - _Tp* __expected, - _Tp __value, - memory_order __success, - memory_order __failure) { - return __atomic_compare_exchange( - std::addressof(__a->__a_value), - __expected, - std::addressof(__value), - false, - __to_gcc_order(__success), - __to_gcc_failure_order(__failure)); -} - -template -_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( - __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) { - return __atomic_compare_exchange( - std::addressof(__a->__a_value), - __expected, - std::addressof(__value), - false, - __to_gcc_order(__success), - __to_gcc_failure_order(__failure)); -} - -template -_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( - volatile __cxx_atomic_base_impl<_Tp>* __a, - _Tp* __expected, - _Tp __value, - memory_order __success, - memory_order __failure) { - return __atomic_compare_exchange( - std::addressof(__a->__a_value), - __expected, - std::addressof(__value), - true, - __to_gcc_order(__success), - __to_gcc_failure_order(__failure)); -} - -template -_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( - __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) { - return __atomic_compare_exchange( - std::addressof(__a->__a_value), - __expected, - std::addressof(__value), - true, - __to_gcc_order(__success), - __to_gcc_failure_order(__failure)); -} - -template -struct __skip_amt { - enum { value = 1 }; -}; - -template -struct __skip_amt<_Tp*> { - enum { value = sizeof(_Tp) }; -}; - -// FIXME: Haven't figured out what the spec says about using arrays with -// atomic_fetch_add. Force a failure rather than creating bad behavior. -template -struct __skip_amt<_Tp[]> {}; -template -struct __skip_amt<_Tp[n]> {}; - -template -_LIBCPP_HIDE_FROM_ABI _Tp -__cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { - return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { - return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp -__cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { - return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { - return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp -__cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { - return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp -__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { - return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp -__cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { - return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { - return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp -__cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { - return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); -} - -template -_LIBCPP_HIDE_FROM_ABI _Tp -__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { - return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); -} - -# define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0) +// +// This file implements support for C11-style atomics +// -#elif _LIBCPP_HAS_C_ATOMIC_IMP +_LIBCPP_BEGIN_NAMESPACE_STD template struct __cxx_atomic_base_impl { _LIBCPP_HIDE_FROM_ABI -# ifndef _LIBCPP_CXX03_LANG +#ifndef _LIBCPP_CXX03_LANG __cxx_atomic_base_impl() _NOEXCEPT = default; -# else +#else __cxx_atomic_base_impl() _NOEXCEPT : __a_value() { } -# endif // _LIBCPP_CXX03_LANG +#endif // _LIBCPP_CXX03_LANG _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp __value) _NOEXCEPT : __a_value(__value) {} _LIBCPP_DISABLE_EXTENSION_WARNING _Atomic(_Tp) __a_value; }; -# define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s) +#define __cxx_atomic_is_lock_free(__s) __c11_atomic_is_lock_free(__s) _LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) _NOEXCEPT { __c11_atomic_thread_fence(static_cast<__memory_order_underlying_t>(__order)); @@ -496,16 +259,6 @@ __cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_o std::addressof(__a->__a_value), __pattern, static_cast<__memory_order_underlying_t>(__order)); } -#endif // _LIBCPP_HAS_GCC_ATOMIC_IMP, _LIBCPP_HAS_C_ATOMIC_IMP - -template > -struct __cxx_atomic_impl : public _Base { - static_assert(is_trivially_copyable<_Tp>::value, "std::atomic requires that 'T' be a trivially copyable type"); - - _LIBCPP_HIDE_FROM_ABI __cxx_atomic_impl() _NOEXCEPT = default; - _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR explicit __cxx_atomic_impl(_Tp __value) _NOEXCEPT : _Base(__value) {} -}; - _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H +#endif // _LIBCPP___ATOMIC_SUPPORT_C11_H diff --git a/libcxx/include/__atomic/support/gcc.h b/libcxx/include/__atomic/support/gcc.h new file mode 100644 index 0000000000000..73c1b1c8070a4 --- /dev/null +++ b/libcxx/include/__atomic/support/gcc.h @@ -0,0 +1,265 @@ +//===----------------------------------------------------------------------===// +// +// 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 _LIBCPP___ATOMIC_SUPPORT_GCC_H +#define _LIBCPP___ATOMIC_SUPPORT_GCC_H + +#include <__atomic/memory_order.h> +#include <__atomic/to_gcc_order.h> +#include <__config> +#include <__memory/addressof.h> +#include <__type_traits/enable_if.h> +#include <__type_traits/is_assignable.h> +#include <__type_traits/remove_const.h> + +#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) +# pragma GCC system_header +#endif + +// +// This file implements support for GCC-style atomics +// + +_LIBCPP_BEGIN_NAMESPACE_STD + +// [atomics.types.generic]p1 guarantees _Tp is trivially copyable. Because +// the default operator= in an object is not volatile, a byte-by-byte copy +// is required. +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp& __a_value, _Tv const& __val) { + __a_value = __val; +} +template ::value, int> = 0> +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_assign_volatile(_Tp volatile& __a_value, _Tv volatile const& __val) { + volatile char* __to = reinterpret_cast(std::addressof(__a_value)); + volatile char* __end = __to + sizeof(_Tp); + volatile const char* __from = reinterpret_cast(std::addressof(__val)); + while (__to != __end) + *__to++ = *__from++; +} + +template +struct __cxx_atomic_base_impl { + _LIBCPP_HIDE_FROM_ABI +#ifndef _LIBCPP_CXX03_LANG + __cxx_atomic_base_impl() _NOEXCEPT = default; +#else + __cxx_atomic_base_impl() _NOEXCEPT : __a_value() { + } +#endif // _LIBCPP_CXX03_LANG + _LIBCPP_CONSTEXPR explicit __cxx_atomic_base_impl(_Tp value) _NOEXCEPT : __a_value(value) {} + _Tp __a_value; +}; + +template +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { + __cxx_atomic_assign_volatile(__a->__a_value, __val); +} + +template +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_init(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val) { + __a->__a_value = __val; +} + +_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_thread_fence(memory_order __order) { + __atomic_thread_fence(__to_gcc_order(__order)); +} + +_LIBCPP_HIDE_FROM_ABI inline void __cxx_atomic_signal_fence(memory_order __order) { + __atomic_signal_fence(__to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_store(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) { + __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI void __cxx_atomic_store(__cxx_atomic_base_impl<_Tp>* __a, _Tp __val, memory_order __order) { + __atomic_store(std::addressof(__a->__a_value), std::addressof(__val), __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const volatile __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { + _Tp __ret; + __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order)); + return __ret; +} + +template +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_load_inplace(const volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, memory_order __order) { + __atomic_load(std::addressof(__a->__a_value), __dst, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI void +__cxx_atomic_load_inplace(const __cxx_atomic_base_impl<_Tp>* __a, _Tp* __dst, memory_order __order) { + __atomic_load(std::addressof(__a->__a_value), __dst, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_load(const __cxx_atomic_base_impl<_Tp>* __a, memory_order __order) { + _Tp __ret; + __atomic_load(std::addressof(__a->__a_value), std::addressof(__ret), __to_gcc_order(__order)); + return __ret; +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_exchange(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) { + _Tp __ret; + __atomic_exchange( + std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order)); + return __ret; +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_exchange(__cxx_atomic_base_impl<_Tp>* __a, _Tp __value, memory_order __order) { + _Tp __ret; + __atomic_exchange( + std::addressof(__a->__a_value), std::addressof(__value), std::addressof(__ret), __to_gcc_order(__order)); + return __ret; +} + +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( + volatile __cxx_atomic_base_impl<_Tp>* __a, + _Tp* __expected, + _Tp __value, + memory_order __success, + memory_order __failure) { + return __atomic_compare_exchange( + std::addressof(__a->__a_value), + __expected, + std::addressof(__value), + false, + __to_gcc_order(__success), + __to_gcc_failure_order(__failure)); +} + +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_strong( + __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) { + return __atomic_compare_exchange( + std::addressof(__a->__a_value), + __expected, + std::addressof(__value), + false, + __to_gcc_order(__success), + __to_gcc_failure_order(__failure)); +} + +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( + volatile __cxx_atomic_base_impl<_Tp>* __a, + _Tp* __expected, + _Tp __value, + memory_order __success, + memory_order __failure) { + return __atomic_compare_exchange( + std::addressof(__a->__a_value), + __expected, + std::addressof(__value), + true, + __to_gcc_order(__success), + __to_gcc_failure_order(__failure)); +} + +template +_LIBCPP_HIDE_FROM_ABI bool __cxx_atomic_compare_exchange_weak( + __cxx_atomic_base_impl<_Tp>* __a, _Tp* __expected, _Tp __value, memory_order __success, memory_order __failure) { + return __atomic_compare_exchange( + std::addressof(__a->__a_value), + __expected, + std::addressof(__value), + true, + __to_gcc_order(__success), + __to_gcc_failure_order(__failure)); +} + +template +struct __skip_amt { + enum { value = 1 }; +}; + +template +struct __skip_amt<_Tp*> { + enum { value = sizeof(_Tp) }; +}; + +// FIXME: Haven't figured out what the spec says about using arrays with +// atomic_fetch_add. Force a failure rather than creating bad behavior. +template +struct __skip_amt<_Tp[]> {}; +template +struct __skip_amt<_Tp[n]> {}; + +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_add(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { + return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_add(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { + return __atomic_fetch_add(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_sub(volatile __cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { + return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_sub(__cxx_atomic_base_impl<_Tp>* __a, _Td __delta, memory_order __order) { + return __atomic_fetch_sub(std::addressof(__a->__a_value), __delta * __skip_amt<_Tp>::value, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_and(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { + return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_and(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { + return __atomic_fetch_and(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_or(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { + return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp __cxx_atomic_fetch_or(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { + return __atomic_fetch_or(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_xor(volatile __cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { + return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); +} + +template +_LIBCPP_HIDE_FROM_ABI _Tp +__cxx_atomic_fetch_xor(__cxx_atomic_base_impl<_Tp>* __a, _Tp __pattern, memory_order __order) { + return __atomic_fetch_xor(std::addressof(__a->__a_value), __pattern, __to_gcc_order(__order)); +} + +#define __cxx_atomic_is_lock_free(__s) __atomic_is_lock_free(__s, 0) + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___ATOMIC_SUPPORT_GCC_H diff --git a/libcxx/include/__cxx03/__algorithm/adjacent_find.h b/libcxx/include/__cxx03/__algorithm/adjacent_find.h index 88036db84de89..6add0f3fe2b53 100644 --- a/libcxx/include/__cxx03/__algorithm/adjacent_find.h +++ b/libcxx/include/__cxx03/__algorithm/adjacent_find.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_ADJACENT_FIND_H -#define _LIBCPP___ALGORITHM_ADJACENT_FIND_H +#ifndef _LIBCPP___CXX03___ALGORITHM_ADJACENT_FIND_H +#define _LIBCPP___CXX03___ALGORITHM_ADJACENT_FIND_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -55,4 +55,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_ADJACENT_FIND_H +#endif // _LIBCPP___CXX03___ALGORITHM_ADJACENT_FIND_H diff --git a/libcxx/include/__cxx03/__algorithm/all_of.h b/libcxx/include/__cxx03/__algorithm/all_of.h index b32d97241506e..fe46ee5fca43c 100644 --- a/libcxx/include/__cxx03/__algorithm/all_of.h +++ b/libcxx/include/__cxx03/__algorithm/all_of.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_ALL_OF_H -#define _LIBCPP___ALGORITHM_ALL_OF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_ALL_OF_H +#define _LIBCPP___CXX03___ALGORITHM_ALL_OF_H #include <__cxx03/__config> @@ -29,4 +29,4 @@ all_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_ALL_OF_H +#endif // _LIBCPP___CXX03___ALGORITHM_ALL_OF_H diff --git a/libcxx/include/__cxx03/__algorithm/any_of.h b/libcxx/include/__cxx03/__algorithm/any_of.h index bd7de96fbef40..26bf3996e8a6f 100644 --- a/libcxx/include/__cxx03/__algorithm/any_of.h +++ b/libcxx/include/__cxx03/__algorithm/any_of.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_ANY_OF_H -#define _LIBCPP___ALGORITHM_ANY_OF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_ANY_OF_H +#define _LIBCPP___CXX03___ALGORITHM_ANY_OF_H #include <__cxx03/__config> @@ -29,4 +29,4 @@ any_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_ANY_OF_H +#endif // _LIBCPP___CXX03___ALGORITHM_ANY_OF_H diff --git a/libcxx/include/__cxx03/__algorithm/binary_search.h b/libcxx/include/__cxx03/__algorithm/binary_search.h index a93c62b32d742..a72da8e396639 100644 --- a/libcxx/include/__cxx03/__algorithm/binary_search.h +++ b/libcxx/include/__cxx03/__algorithm/binary_search.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_BINARY_SEARCH_H -#define _LIBCPP___ALGORITHM_BINARY_SEARCH_H +#ifndef _LIBCPP___CXX03___ALGORITHM_BINARY_SEARCH_H +#define _LIBCPP___CXX03___ALGORITHM_BINARY_SEARCH_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -36,4 +36,4 @@ binary_search(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __va _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_BINARY_SEARCH_H +#endif // _LIBCPP___CXX03___ALGORITHM_BINARY_SEARCH_H diff --git a/libcxx/include/__cxx03/__algorithm/clamp.h b/libcxx/include/__cxx03/__algorithm/clamp.h index e5e4dbf774dc3..0e4bb0eb6b950 100644 --- a/libcxx/include/__cxx03/__algorithm/clamp.h +++ b/libcxx/include/__cxx03/__algorithm/clamp.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_CLAMP_H -#define _LIBCPP___ALGORITHM_CLAMP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_CLAMP_H +#define _LIBCPP___CXX03___ALGORITHM_CLAMP_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__assert> @@ -41,4 +41,4 @@ clamp(_LIBCPP_LIFETIMEBOUND const _Tp& __v, _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_CLAMP_H +#endif // _LIBCPP___CXX03___ALGORITHM_CLAMP_H diff --git a/libcxx/include/__cxx03/__algorithm/comp.h b/libcxx/include/__cxx03/__algorithm/comp.h index f01e395dc21ea..0c638b4e4a651 100644 --- a/libcxx/include/__cxx03/__algorithm/comp.h +++ b/libcxx/include/__cxx03/__algorithm/comp.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_COMP_H -#define _LIBCPP___ALGORITHM_COMP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_COMP_H +#define _LIBCPP___CXX03___ALGORITHM_COMP_H #include <__cxx03/__config> #include <__cxx03/__type_traits/desugars_to.h> @@ -46,4 +46,4 @@ inline const bool __desugars_to_v<__less_tag, __less<>, _Tp, _Tp> = true; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_COMP_H +#endif // _LIBCPP___CXX03___ALGORITHM_COMP_H diff --git a/libcxx/include/__cxx03/__algorithm/comp_ref_type.h b/libcxx/include/__cxx03/__algorithm/comp_ref_type.h index 413bf30c6a64c..ab793da0ad293 100644 --- a/libcxx/include/__cxx03/__algorithm/comp_ref_type.h +++ b/libcxx/include/__cxx03/__algorithm/comp_ref_type.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_COMP_REF_TYPE_H -#define _LIBCPP___ALGORITHM_COMP_REF_TYPE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_COMP_REF_TYPE_H +#define _LIBCPP___CXX03___ALGORITHM_COMP_REF_TYPE_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -64,4 +64,4 @@ using __comp_ref_type = _Comp&; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_COMP_REF_TYPE_H +#endif // _LIBCPP___CXX03___ALGORITHM_COMP_REF_TYPE_H diff --git a/libcxx/include/__cxx03/__algorithm/copy.h b/libcxx/include/__cxx03/__algorithm/copy.h index 6de8df3f980fe..2aa0ab78b7858 100644 --- a/libcxx/include/__cxx03/__algorithm/copy.h +++ b/libcxx/include/__cxx03/__algorithm/copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_COPY_H -#define _LIBCPP___ALGORITHM_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_COPY_H #include <__cxx03/__algorithm/copy_move_common.h> #include <__cxx03/__algorithm/for_each_segment.h> @@ -120,4 +120,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/copy_backward.h b/libcxx/include/__cxx03/__algorithm/copy_backward.h index dd7ff8ada5280..9262d13d6c175 100644 --- a/libcxx/include/__cxx03/__algorithm/copy_backward.h +++ b/libcxx/include/__cxx03/__algorithm/copy_backward.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_COPY_BACKWARD_H -#define _LIBCPP___ALGORITHM_COPY_BACKWARD_H +#ifndef _LIBCPP___CXX03___ALGORITHM_COPY_BACKWARD_H +#define _LIBCPP___CXX03___ALGORITHM_COPY_BACKWARD_H #include <__cxx03/__algorithm/copy_move_common.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -134,4 +134,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_COPY_BACKWARD_H +#endif // _LIBCPP___CXX03___ALGORITHM_COPY_BACKWARD_H diff --git a/libcxx/include/__cxx03/__algorithm/copy_if.h b/libcxx/include/__cxx03/__algorithm/copy_if.h index 345b12878d333..2db0c26fb86be 100644 --- a/libcxx/include/__cxx03/__algorithm/copy_if.h +++ b/libcxx/include/__cxx03/__algorithm/copy_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_COPY_IF_H -#define _LIBCPP___ALGORITHM_COPY_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_COPY_IF_H +#define _LIBCPP___CXX03___ALGORITHM_COPY_IF_H #include <__cxx03/__config> @@ -31,4 +31,4 @@ copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __result, _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_COPY_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_COPY_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/copy_move_common.h b/libcxx/include/__cxx03/__algorithm/copy_move_common.h index c598307025176..637b5a01daa75 100644 --- a/libcxx/include/__cxx03/__algorithm/copy_move_common.h +++ b/libcxx/include/__cxx03/__algorithm/copy_move_common.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H -#define _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H +#ifndef _LIBCPP___CXX03___ALGORITHM_COPY_MOVE_COMMON_H +#define _LIBCPP___CXX03___ALGORITHM_COPY_MOVE_COMMON_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/unwrap_iter.h> @@ -111,4 +111,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_COPY_MOVE_COMMON_H +#endif // _LIBCPP___CXX03___ALGORITHM_COPY_MOVE_COMMON_H diff --git a/libcxx/include/__cxx03/__algorithm/copy_n.h b/libcxx/include/__cxx03/__algorithm/copy_n.h index 14f1402944335..aedb232b1bd5e 100644 --- a/libcxx/include/__cxx03/__algorithm/copy_n.h +++ b/libcxx/include/__cxx03/__algorithm/copy_n.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_COPY_N_H -#define _LIBCPP___ALGORITHM_COPY_N_H +#ifndef _LIBCPP___CXX03___ALGORITHM_COPY_N_H +#define _LIBCPP___CXX03___ALGORITHM_COPY_N_H #include <__cxx03/__algorithm/copy.h> #include <__cxx03/__config> @@ -57,4 +57,4 @@ copy_n(_InputIterator __first, _Size __orig_n, _OutputIterator __result) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_COPY_N_H +#endif // _LIBCPP___CXX03___ALGORITHM_COPY_N_H diff --git a/libcxx/include/__cxx03/__algorithm/count.h b/libcxx/include/__cxx03/__algorithm/count.h index b7024dc8c6318..7c1fc3e579898 100644 --- a/libcxx/include/__cxx03/__algorithm/count.h +++ b/libcxx/include/__cxx03/__algorithm/count.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_COUNT_H -#define _LIBCPP___ALGORITHM_COUNT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_COUNT_H +#define _LIBCPP___CXX03___ALGORITHM_COUNT_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/min.h> @@ -89,4 +89,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_COUNT_H +#endif // _LIBCPP___CXX03___ALGORITHM_COUNT_H diff --git a/libcxx/include/__cxx03/__algorithm/count_if.h b/libcxx/include/__cxx03/__algorithm/count_if.h index eeb42052b08ae..d333e86189176 100644 --- a/libcxx/include/__cxx03/__algorithm/count_if.h +++ b/libcxx/include/__cxx03/__algorithm/count_if.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_COUNT_IF_H -#define _LIBCPP___ALGORITHM_COUNT_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_COUNT_IF_H +#define _LIBCPP___CXX03___ALGORITHM_COUNT_IF_H #include <__cxx03/__config> #include <__cxx03/__iterator/iterator_traits.h> @@ -32,4 +32,4 @@ count_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_COUNT_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_COUNT_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/equal.h b/libcxx/include/__cxx03/__algorithm/equal.h index a4d0a999b1819..4e478932981e7 100644 --- a/libcxx/include/__cxx03/__algorithm/equal.h +++ b/libcxx/include/__cxx03/__algorithm/equal.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_EQUAL_H -#define _LIBCPP___ALGORITHM_EQUAL_H +#ifndef _LIBCPP___CXX03___ALGORITHM_EQUAL_H +#define _LIBCPP___CXX03___ALGORITHM_EQUAL_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/unwrap_iter.h> @@ -130,4 +130,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_EQUAL_H +#endif // _LIBCPP___CXX03___ALGORITHM_EQUAL_H diff --git a/libcxx/include/__cxx03/__algorithm/equal_range.h b/libcxx/include/__cxx03/__algorithm/equal_range.h index 9abda2bd2e36f..4b3126a2840cf 100644 --- a/libcxx/include/__cxx03/__algorithm/equal_range.h +++ b/libcxx/include/__cxx03/__algorithm/equal_range.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_EQUAL_RANGE_H -#define _LIBCPP___ALGORITHM_EQUAL_RANGE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_EQUAL_RANGE_H +#define _LIBCPP___CXX03___ALGORITHM_EQUAL_RANGE_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -82,4 +82,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_EQUAL_RANGE_H +#endif // _LIBCPP___CXX03___ALGORITHM_EQUAL_RANGE_H diff --git a/libcxx/include/__cxx03/__algorithm/fill.h b/libcxx/include/__cxx03/__algorithm/fill.h index 5da0f4457daa6..4aaf2744e8a58 100644 --- a/libcxx/include/__cxx03/__algorithm/fill.h +++ b/libcxx/include/__cxx03/__algorithm/fill.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_FILL_H -#define _LIBCPP___ALGORITHM_FILL_H +#ifndef _LIBCPP___CXX03___ALGORITHM_FILL_H +#define _LIBCPP___CXX03___ALGORITHM_FILL_H #include <__cxx03/__algorithm/fill_n.h> #include <__cxx03/__config> @@ -42,4 +42,4 @@ fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_FILL_H +#endif // _LIBCPP___CXX03___ALGORITHM_FILL_H diff --git a/libcxx/include/__cxx03/__algorithm/fill_n.h b/libcxx/include/__cxx03/__algorithm/fill_n.h index fd548f27056a1..99b712c7b0360 100644 --- a/libcxx/include/__cxx03/__algorithm/fill_n.h +++ b/libcxx/include/__cxx03/__algorithm/fill_n.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_FILL_N_H -#define _LIBCPP___ALGORITHM_FILL_N_H +#ifndef _LIBCPP___CXX03___ALGORITHM_FILL_N_H +#define _LIBCPP___CXX03___ALGORITHM_FILL_N_H #include <__cxx03/__algorithm/min.h> #include <__cxx03/__config> @@ -95,4 +95,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_FILL_N_H +#endif // _LIBCPP___CXX03___ALGORITHM_FILL_N_H diff --git a/libcxx/include/__cxx03/__algorithm/find.h b/libcxx/include/__cxx03/__algorithm/find.h index 7a48a449c897b..ff5ac9b8b1bd0 100644 --- a/libcxx/include/__cxx03/__algorithm/find.h +++ b/libcxx/include/__cxx03/__algorithm/find.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_FIND_H -#define _LIBCPP___ALGORITHM_FIND_H +#ifndef _LIBCPP___CXX03___ALGORITHM_FIND_H +#define _LIBCPP___CXX03___ALGORITHM_FIND_H #include <__cxx03/__algorithm/find_segment_if.h> #include <__cxx03/__algorithm/min.h> @@ -178,4 +178,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_FIND_H +#endif // _LIBCPP___CXX03___ALGORITHM_FIND_H diff --git a/libcxx/include/__cxx03/__algorithm/find_end.h b/libcxx/include/__cxx03/__algorithm/find_end.h index 34a45e2c66fae..3fa046bd0df3e 100644 --- a/libcxx/include/__cxx03/__algorithm/find_end.h +++ b/libcxx/include/__cxx03/__algorithm/find_end.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_FIND_END_OF_H -#define _LIBCPP___ALGORITHM_FIND_END_OF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_FIND_END_OF_H +#define _LIBCPP___CXX03___ALGORITHM_FIND_END_OF_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -222,4 +222,4 @@ find_end(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_FIND_END_OF_H +#endif // _LIBCPP___CXX03___ALGORITHM_FIND_END_OF_H diff --git a/libcxx/include/__cxx03/__algorithm/find_first_of.h b/libcxx/include/__cxx03/__algorithm/find_first_of.h index 05eb85fd663d2..b1b3e5f3be01e 100644 --- a/libcxx/include/__cxx03/__algorithm/find_first_of.h +++ b/libcxx/include/__cxx03/__algorithm/find_first_of.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_FIND_FIRST_OF_H -#define _LIBCPP___ALGORITHM_FIND_FIRST_OF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_FIND_FIRST_OF_H +#define _LIBCPP___CXX03___ALGORITHM_FIND_FIRST_OF_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__config> @@ -52,4 +52,4 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _Fo _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_FIND_FIRST_OF_H +#endif // _LIBCPP___CXX03___ALGORITHM_FIND_FIRST_OF_H diff --git a/libcxx/include/__cxx03/__algorithm/find_if.h b/libcxx/include/__cxx03/__algorithm/find_if.h index b0150e539f9ab..ca4139c86787c 100644 --- a/libcxx/include/__cxx03/__algorithm/find_if.h +++ b/libcxx/include/__cxx03/__algorithm/find_if.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_FIND_IF_H -#define _LIBCPP___ALGORITHM_FIND_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_FIND_IF_H +#define _LIBCPP___CXX03___ALGORITHM_FIND_IF_H #include <__cxx03/__config> @@ -29,4 +29,4 @@ find_if(_InputIterator __first, _InputIterator __last, _Predicate __pred) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_FIND_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_FIND_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/find_if_not.h b/libcxx/include/__cxx03/__algorithm/find_if_not.h index 67d9a7deb2edd..a662dfbddfbb9 100644 --- a/libcxx/include/__cxx03/__algorithm/find_if_not.h +++ b/libcxx/include/__cxx03/__algorithm/find_if_not.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_FIND_IF_NOT_H -#define _LIBCPP___ALGORITHM_FIND_IF_NOT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_FIND_IF_NOT_H +#define _LIBCPP___CXX03___ALGORITHM_FIND_IF_NOT_H #include <__cxx03/__config> @@ -29,4 +29,4 @@ find_if_not(_InputIterator __first, _InputIterator __last, _Predicate __pred) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_FIND_IF_NOT_H +#endif // _LIBCPP___CXX03___ALGORITHM_FIND_IF_NOT_H diff --git a/libcxx/include/__cxx03/__algorithm/find_segment_if.h b/libcxx/include/__cxx03/__algorithm/find_segment_if.h index a6c016234418e..3475e9e8bdacd 100644 --- a/libcxx/include/__cxx03/__algorithm/find_segment_if.h +++ b/libcxx/include/__cxx03/__algorithm/find_segment_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_FIND_SEGMENT_IF_H -#define _LIBCPP___ALGORITHM_FIND_SEGMENT_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_FIND_SEGMENT_IF_H +#define _LIBCPP___CXX03___ALGORITHM_FIND_SEGMENT_IF_H #include <__cxx03/__config> #include <__cxx03/__iterator/segmented_iterator.h> @@ -59,4 +59,4 @@ __find_segment_if(_SegmentedIterator __first, _SegmentedIterator __last, _Pred _ _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_FIND_SEGMENT_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_FIND_SEGMENT_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/fold.h b/libcxx/include/__cxx03/__algorithm/fold.h index 7e9c745bbbdb2..5ec0d747c009c 100644 --- a/libcxx/include/__cxx03/__algorithm/fold.h +++ b/libcxx/include/__cxx03/__algorithm/fold.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_FOLD_H -#define _LIBCPP___ALGORITHM_FOLD_H +#ifndef _LIBCPP___CXX03___ALGORITHM_FOLD_H +#define _LIBCPP___CXX03___ALGORITHM_FOLD_H #include <__cxx03/__concepts/assignable.h> #include <__cxx03/__concepts/convertible_to.h> @@ -125,4 +125,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_FOLD_H +#endif // _LIBCPP___CXX03___ALGORITHM_FOLD_H diff --git a/libcxx/include/__cxx03/__algorithm/for_each.h b/libcxx/include/__cxx03/__algorithm/for_each.h index d2b19310c60f5..a6faf805fe9cf 100644 --- a/libcxx/include/__cxx03/__algorithm/for_each.h +++ b/libcxx/include/__cxx03/__algorithm/for_each.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_FOR_EACH_H -#define _LIBCPP___ALGORITHM_FOR_EACH_H +#ifndef _LIBCPP___CXX03___ALGORITHM_FOR_EACH_H +#define _LIBCPP___CXX03___ALGORITHM_FOR_EACH_H #include <__cxx03/__algorithm/for_each_segment.h> #include <__cxx03/__config> @@ -54,4 +54,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_FOR_EACH_H +#endif // _LIBCPP___CXX03___ALGORITHM_FOR_EACH_H diff --git a/libcxx/include/__cxx03/__algorithm/for_each_n.h b/libcxx/include/__cxx03/__algorithm/for_each_n.h index 7b8c40eacf967..486a5266ad011 100644 --- a/libcxx/include/__cxx03/__algorithm/for_each_n.h +++ b/libcxx/include/__cxx03/__algorithm/for_each_n.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_FOR_EACH_N_H -#define _LIBCPP___ALGORITHM_FOR_EACH_N_H +#ifndef _LIBCPP___CXX03___ALGORITHM_FOR_EACH_N_H +#define _LIBCPP___CXX03___ALGORITHM_FOR_EACH_N_H #include <__cxx03/__config> #include <__cxx03/__utility/convert_to_integral.h> @@ -38,4 +38,4 @@ for_each_n(_InputIterator __first, _Size __orig_n, _Function __f) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_FOR_EACH_N_H +#endif // _LIBCPP___CXX03___ALGORITHM_FOR_EACH_N_H diff --git a/libcxx/include/__cxx03/__algorithm/for_each_segment.h b/libcxx/include/__cxx03/__algorithm/for_each_segment.h index 50c4b28deba02..02b4a1799d6a8 100644 --- a/libcxx/include/__cxx03/__algorithm/for_each_segment.h +++ b/libcxx/include/__cxx03/__algorithm/for_each_segment.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H -#define _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_FOR_EACH_SEGMENT_H +#define _LIBCPP___CXX03___ALGORITHM_FOR_EACH_SEGMENT_H #include <__cxx03/__config> #include <__cxx03/__iterator/segmented_iterator.h> @@ -50,4 +50,4 @@ __for_each_segment(_SegmentedIterator __first, _SegmentedIterator __last, _Funct _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_FOR_EACH_SEGMENT_H +#endif // _LIBCPP___CXX03___ALGORITHM_FOR_EACH_SEGMENT_H diff --git a/libcxx/include/__cxx03/__algorithm/generate.h b/libcxx/include/__cxx03/__algorithm/generate.h index 14da75cd44ceb..fa1929b639ad1 100644 --- a/libcxx/include/__cxx03/__algorithm/generate.h +++ b/libcxx/include/__cxx03/__algorithm/generate.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_GENERATE_H -#define _LIBCPP___ALGORITHM_GENERATE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_GENERATE_H +#define _LIBCPP___CXX03___ALGORITHM_GENERATE_H #include <__cxx03/__config> @@ -26,4 +26,4 @@ generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __gen) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_GENERATE_H +#endif // _LIBCPP___CXX03___ALGORITHM_GENERATE_H diff --git a/libcxx/include/__cxx03/__algorithm/generate_n.h b/libcxx/include/__cxx03/__algorithm/generate_n.h index 32cc86911815c..5a421131070e9 100644 --- a/libcxx/include/__cxx03/__algorithm/generate_n.h +++ b/libcxx/include/__cxx03/__algorithm/generate_n.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_GENERATE_N_H -#define _LIBCPP___ALGORITHM_GENERATE_N_H +#ifndef _LIBCPP___CXX03___ALGORITHM_GENERATE_N_H +#define _LIBCPP___CXX03___ALGORITHM_GENERATE_N_H #include <__cxx03/__config> #include <__cxx03/__utility/convert_to_integral.h> @@ -30,4 +30,4 @@ generate_n(_OutputIterator __first, _Size __orig_n, _Generator __gen) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_GENERATE_N_H +#endif // _LIBCPP___CXX03___ALGORITHM_GENERATE_N_H diff --git a/libcxx/include/__cxx03/__algorithm/half_positive.h b/libcxx/include/__cxx03/__algorithm/half_positive.h index 4378964d9d836..a436a6086b5e9 100644 --- a/libcxx/include/__cxx03/__algorithm/half_positive.h +++ b/libcxx/include/__cxx03/__algorithm/half_positive.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_HALF_POSITIVE_H -#define _LIBCPP___ALGORITHM_HALF_POSITIVE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_HALF_POSITIVE_H +#define _LIBCPP___CXX03___ALGORITHM_HALF_POSITIVE_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -34,4 +34,4 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR _Tp __half_positive(_Tp __value) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_HALF_POSITIVE_H +#endif // _LIBCPP___CXX03___ALGORITHM_HALF_POSITIVE_H diff --git a/libcxx/include/__cxx03/__algorithm/in_found_result.h b/libcxx/include/__cxx03/__algorithm/in_found_result.h index 0f4895dab437e..234e17cbd019a 100644 --- a/libcxx/include/__cxx03/__algorithm/in_found_result.h +++ b/libcxx/include/__cxx03/__algorithm/in_found_result.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H -#define _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_IN_FOUND_RESULT_H +#define _LIBCPP___CXX03___ALGORITHM_IN_FOUND_RESULT_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__config> @@ -51,4 +51,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_IN_FOUND_RESULT_H +#endif // _LIBCPP___CXX03___ALGORITHM_IN_FOUND_RESULT_H diff --git a/libcxx/include/__cxx03/__algorithm/in_fun_result.h b/libcxx/include/__cxx03/__algorithm/in_fun_result.h index 998d4599ceac8..402fbecc3df04 100644 --- a/libcxx/include/__cxx03/__algorithm/in_fun_result.h +++ b/libcxx/include/__cxx03/__algorithm/in_fun_result.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_IN_FUN_RESULT_H -#define _LIBCPP___ALGORITHM_IN_FUN_RESULT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_IN_FUN_RESULT_H +#define _LIBCPP___CXX03___ALGORITHM_IN_FUN_RESULT_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__config> @@ -51,4 +51,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_IN_FUN_RESULT_H +#endif // _LIBCPP___CXX03___ALGORITHM_IN_FUN_RESULT_H diff --git a/libcxx/include/__cxx03/__algorithm/in_in_out_result.h b/libcxx/include/__cxx03/__algorithm/in_in_out_result.h index bb3a7e5466de0..cb14a7e654faa 100644 --- a/libcxx/include/__cxx03/__algorithm/in_in_out_result.h +++ b/libcxx/include/__cxx03/__algorithm/in_in_out_result.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H -#define _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_IN_IN_OUT_RESULT_H +#define _LIBCPP___CXX03___ALGORITHM_IN_IN_OUT_RESULT_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__config> @@ -56,4 +56,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_IN_IN_OUT_RESULT_H +#endif // _LIBCPP___CXX03___ALGORITHM_IN_IN_OUT_RESULT_H diff --git a/libcxx/include/__cxx03/__algorithm/in_in_result.h b/libcxx/include/__cxx03/__algorithm/in_in_result.h index 12f1b572c5870..3ef349f87ff6c 100644 --- a/libcxx/include/__cxx03/__algorithm/in_in_result.h +++ b/libcxx/include/__cxx03/__algorithm/in_in_result.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_IN_IN_RESULT_H -#define _LIBCPP___ALGORITHM_IN_IN_RESULT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_IN_IN_RESULT_H +#define _LIBCPP___CXX03___ALGORITHM_IN_IN_RESULT_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__config> @@ -53,4 +53,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_IN_IN_RESULT_H +#endif // _LIBCPP___CXX03___ALGORITHM_IN_IN_RESULT_H diff --git a/libcxx/include/__cxx03/__algorithm/in_out_out_result.h b/libcxx/include/__cxx03/__algorithm/in_out_out_result.h index c7d18535d1014..de67ac89fefeb 100644 --- a/libcxx/include/__cxx03/__algorithm/in_out_out_result.h +++ b/libcxx/include/__cxx03/__algorithm/in_out_out_result.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H -#define _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_IN_OUT_OUT_RESULT_H +#define _LIBCPP___CXX03___ALGORITHM_IN_OUT_OUT_RESULT_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__config> @@ -54,4 +54,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_IN_OUT_OUT_RESULT_H +#endif // _LIBCPP___CXX03___ALGORITHM_IN_OUT_OUT_RESULT_H diff --git a/libcxx/include/__cxx03/__algorithm/in_out_result.h b/libcxx/include/__cxx03/__algorithm/in_out_result.h index 66bd1a1666988..e80f5fd7ba77b 100644 --- a/libcxx/include/__cxx03/__algorithm/in_out_result.h +++ b/libcxx/include/__cxx03/__algorithm/in_out_result.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_IN_OUT_RESULT_H -#define _LIBCPP___ALGORITHM_IN_OUT_RESULT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_IN_OUT_RESULT_H +#define _LIBCPP___CXX03___ALGORITHM_IN_OUT_RESULT_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__config> @@ -53,4 +53,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_IN_OUT_RESULT_H +#endif // _LIBCPP___CXX03___ALGORITHM_IN_OUT_RESULT_H diff --git a/libcxx/include/__cxx03/__algorithm/includes.h b/libcxx/include/__cxx03/__algorithm/includes.h index 6d3eb44bb8c44..24b46d1f10cb5 100644 --- a/libcxx/include/__cxx03/__algorithm/includes.h +++ b/libcxx/include/__cxx03/__algorithm/includes.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_INCLUDES_H -#define _LIBCPP___ALGORITHM_INCLUDES_H +#ifndef _LIBCPP___CXX03___ALGORITHM_INCLUDES_H +#define _LIBCPP___CXX03___ALGORITHM_INCLUDES_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -76,4 +76,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_INCLUDES_H +#endif // _LIBCPP___CXX03___ALGORITHM_INCLUDES_H diff --git a/libcxx/include/__cxx03/__algorithm/inplace_merge.h b/libcxx/include/__cxx03/__algorithm/inplace_merge.h index 3816ba5793c0d..187969dcc4029 100644 --- a/libcxx/include/__cxx03/__algorithm/inplace_merge.h +++ b/libcxx/include/__cxx03/__algorithm/inplace_merge.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_INPLACE_MERGE_H -#define _LIBCPP___ALGORITHM_INPLACE_MERGE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_INPLACE_MERGE_H +#define _LIBCPP___CXX03___ALGORITHM_INPLACE_MERGE_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -237,4 +237,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_INPLACE_MERGE_H +#endif // _LIBCPP___CXX03___ALGORITHM_INPLACE_MERGE_H diff --git a/libcxx/include/__cxx03/__algorithm/is_heap.h b/libcxx/include/__cxx03/__algorithm/is_heap.h index dde4bfb6ff2db..c19adb84ba570 100644 --- a/libcxx/include/__cxx03/__algorithm/is_heap.h +++ b/libcxx/include/__cxx03/__algorithm/is_heap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_IS_HEAP_H -#define _LIBCPP___ALGORITHM_IS_HEAP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_IS_HEAP_H +#define _LIBCPP___CXX03___ALGORITHM_IS_HEAP_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -35,4 +35,4 @@ is_heap(_RandomAccessIterator __first, _RandomAccessIterator __last) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_IS_HEAP_H +#endif // _LIBCPP___CXX03___ALGORITHM_IS_HEAP_H diff --git a/libcxx/include/__cxx03/__algorithm/is_heap_until.h b/libcxx/include/__cxx03/__algorithm/is_heap_until.h index d46dd343115c3..e3a6d9769fcc5 100644 --- a/libcxx/include/__cxx03/__algorithm/is_heap_until.h +++ b/libcxx/include/__cxx03/__algorithm/is_heap_until.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H -#define _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H +#ifndef _LIBCPP___CXX03___ALGORITHM_IS_HEAP_UNTIL_H +#define _LIBCPP___CXX03___ALGORITHM_IS_HEAP_UNTIL_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -59,4 +59,4 @@ is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_IS_HEAP_UNTIL_H +#endif // _LIBCPP___CXX03___ALGORITHM_IS_HEAP_UNTIL_H diff --git a/libcxx/include/__cxx03/__algorithm/is_partitioned.h b/libcxx/include/__cxx03/__algorithm/is_partitioned.h index 8bd202f3e2429..a7dff7bf42544 100644 --- a/libcxx/include/__cxx03/__algorithm/is_partitioned.h +++ b/libcxx/include/__cxx03/__algorithm/is_partitioned.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_IS_PARTITIONED_H -#define _LIBCPP___ALGORITHM_IS_PARTITIONED_H +#ifndef _LIBCPP___CXX03___ALGORITHM_IS_PARTITIONED_H +#define _LIBCPP___CXX03___ALGORITHM_IS_PARTITIONED_H #include <__cxx03/__config> @@ -34,4 +34,4 @@ is_partitioned(_InputIterator __first, _InputIterator __last, _Predicate __pred) _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_IS_PARTITIONED_H +#endif // _LIBCPP___CXX03___ALGORITHM_IS_PARTITIONED_H diff --git a/libcxx/include/__cxx03/__algorithm/is_permutation.h b/libcxx/include/__cxx03/__algorithm/is_permutation.h index 0274ba98fcd16..fd29e82656a3c 100644 --- a/libcxx/include/__cxx03/__algorithm/is_permutation.h +++ b/libcxx/include/__cxx03/__algorithm/is_permutation.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_IS_PERMUTATION_H -#define _LIBCPP___ALGORITHM_IS_PERMUTATION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_IS_PERMUTATION_H +#define _LIBCPP___CXX03___ALGORITHM_IS_PERMUTATION_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -305,4 +305,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_IS_PERMUTATION_H +#endif // _LIBCPP___CXX03___ALGORITHM_IS_PERMUTATION_H diff --git a/libcxx/include/__cxx03/__algorithm/is_sorted.h b/libcxx/include/__cxx03/__algorithm/is_sorted.h index 0a003a86b9913..1318f5baf8394 100644 --- a/libcxx/include/__cxx03/__algorithm/is_sorted.h +++ b/libcxx/include/__cxx03/__algorithm/is_sorted.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_IS_SORTED_H -#define _LIBCPP___ALGORITHM_IS_SORTED_H +#ifndef _LIBCPP___CXX03___ALGORITHM_IS_SORTED_H +#define _LIBCPP___CXX03___ALGORITHM_IS_SORTED_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -35,4 +35,4 @@ is_sorted(_ForwardIterator __first, _ForwardIterator __last) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_IS_SORTED_H +#endif // _LIBCPP___CXX03___ALGORITHM_IS_SORTED_H diff --git a/libcxx/include/__cxx03/__algorithm/is_sorted_until.h b/libcxx/include/__cxx03/__algorithm/is_sorted_until.h index eb90e5dd88e67..f97fb7c2e53ef 100644 --- a/libcxx/include/__cxx03/__algorithm/is_sorted_until.h +++ b/libcxx/include/__cxx03/__algorithm/is_sorted_until.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H -#define _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H +#ifndef _LIBCPP___CXX03___ALGORITHM_IS_SORTED_UNTIL_H +#define _LIBCPP___CXX03___ALGORITHM_IS_SORTED_UNTIL_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -48,4 +48,4 @@ is_sorted_until(_ForwardIterator __first, _ForwardIterator __last) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_IS_SORTED_UNTIL_H +#endif // _LIBCPP___CXX03___ALGORITHM_IS_SORTED_UNTIL_H diff --git a/libcxx/include/__cxx03/__algorithm/iter_swap.h b/libcxx/include/__cxx03/__algorithm/iter_swap.h index 837a603d23e32..4fcbcdcf1e050 100644 --- a/libcxx/include/__cxx03/__algorithm/iter_swap.h +++ b/libcxx/include/__cxx03/__algorithm/iter_swap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_ITER_SWAP_H -#define _LIBCPP___ALGORITHM_ITER_SWAP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_ITER_SWAP_H +#define _LIBCPP___CXX03___ALGORITHM_ITER_SWAP_H #include <__cxx03/__config> #include <__cxx03/__utility/declval.h> @@ -28,4 +28,4 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void iter_swap(_Forwa _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_ITER_SWAP_H +#endif // _LIBCPP___CXX03___ALGORITHM_ITER_SWAP_H diff --git a/libcxx/include/__cxx03/__algorithm/iterator_operations.h b/libcxx/include/__cxx03/__algorithm/iterator_operations.h index b4f1f9e3ffca9..24973b66e4f96 100644 --- a/libcxx/include/__cxx03/__algorithm/iterator_operations.h +++ b/libcxx/include/__cxx03/__algorithm/iterator_operations.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H -#define _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H +#ifndef _LIBCPP___CXX03___ALGORITHM_ITERATOR_OPERATIONS_H +#define _LIBCPP___CXX03___ALGORITHM_ITERATOR_OPERATIONS_H #include <__cxx03/__algorithm/iter_swap.h> #include <__cxx03/__algorithm/ranges_iterator_concept.h> @@ -220,4 +220,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_ITERATOR_OPERATIONS_H +#endif // _LIBCPP___CXX03___ALGORITHM_ITERATOR_OPERATIONS_H diff --git a/libcxx/include/__cxx03/__algorithm/lexicographical_compare.h b/libcxx/include/__cxx03/__algorithm/lexicographical_compare.h index e3d93be6177e7..b019e4b5021b4 100644 --- a/libcxx/include/__cxx03/__algorithm/lexicographical_compare.h +++ b/libcxx/include/__cxx03/__algorithm/lexicographical_compare.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H -#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H +#define _LIBCPP___CXX03___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -54,4 +54,4 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 boo _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H +#endif // _LIBCPP___CXX03___ALGORITHM_LEXICOGRAPHICAL_COMPARE_H diff --git a/libcxx/include/__cxx03/__algorithm/lexicographical_compare_three_way.h b/libcxx/include/__cxx03/__algorithm/lexicographical_compare_three_way.h index bea67a7937659..2fc53636abbd4 100644 --- a/libcxx/include/__cxx03/__algorithm/lexicographical_compare_three_way.h +++ b/libcxx/include/__cxx03/__algorithm/lexicographical_compare_three_way.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H -#define _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H +#define _LIBCPP___CXX03___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H #include <__cxx03/__algorithm/min.h> #include <__cxx03/__algorithm/three_way_comp_ref_type.h> @@ -122,4 +122,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H +#endif // _LIBCPP___CXX03___ALGORITHM_LEXICOGRAPHICAL_COMPARE_THREE_WAY_H diff --git a/libcxx/include/__cxx03/__algorithm/lower_bound.h b/libcxx/include/__cxx03/__algorithm/lower_bound.h index 844674cb78604..810792bfe8fe1 100644 --- a/libcxx/include/__cxx03/__algorithm/lower_bound.h +++ b/libcxx/include/__cxx03/__algorithm/lower_bound.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_LOWER_BOUND_H -#define _LIBCPP___ALGORITHM_LOWER_BOUND_H +#ifndef _LIBCPP___CXX03___ALGORITHM_LOWER_BOUND_H +#define _LIBCPP___CXX03___ALGORITHM_LOWER_BOUND_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/half_positive.h> @@ -106,4 +106,4 @@ lower_bound(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __valu _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_LOWER_BOUND_H +#endif // _LIBCPP___CXX03___ALGORITHM_LOWER_BOUND_H diff --git a/libcxx/include/__cxx03/__algorithm/make_heap.h b/libcxx/include/__cxx03/__algorithm/make_heap.h index 5239a99083f50..35a7f7bf9779f 100644 --- a/libcxx/include/__cxx03/__algorithm/make_heap.h +++ b/libcxx/include/__cxx03/__algorithm/make_heap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MAKE_HEAP_H -#define _LIBCPP___ALGORITHM_MAKE_HEAP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MAKE_HEAP_H +#define _LIBCPP___CXX03___ALGORITHM_MAKE_HEAP_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -57,4 +57,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_MAKE_HEAP_H +#endif // _LIBCPP___CXX03___ALGORITHM_MAKE_HEAP_H diff --git a/libcxx/include/__cxx03/__algorithm/make_projected.h b/libcxx/include/__cxx03/__algorithm/make_projected.h index 8368e269385f4..ac17c2bba7ba8 100644 --- a/libcxx/include/__cxx03/__algorithm/make_projected.h +++ b/libcxx/include/__cxx03/__algorithm/make_projected.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MAKE_PROJECTED_H -#define _LIBCPP___ALGORITHM_MAKE_PROJECTED_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MAKE_PROJECTED_H +#define _LIBCPP___CXX03___ALGORITHM_MAKE_PROJECTED_H #include <__cxx03/__concepts/same_as.h> #include <__cxx03/__config> @@ -103,4 +103,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___ALGORITHM_MAKE_PROJECTED_H +#endif // _LIBCPP___CXX03___ALGORITHM_MAKE_PROJECTED_H diff --git a/libcxx/include/__cxx03/__algorithm/max.h b/libcxx/include/__cxx03/__algorithm/max.h index 983e81cd24bc4..7726d16827157 100644 --- a/libcxx/include/__cxx03/__algorithm/max.h +++ b/libcxx/include/__cxx03/__algorithm/max.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MAX_H -#define _LIBCPP___ALGORITHM_MAX_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MAX_H +#define _LIBCPP___CXX03___ALGORITHM_MAX_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -55,4 +55,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_MAX_H +#endif // _LIBCPP___CXX03___ALGORITHM_MAX_H diff --git a/libcxx/include/__cxx03/__algorithm/max_element.h b/libcxx/include/__cxx03/__algorithm/max_element.h index 686c116ab0105..20a22e74c8be7 100644 --- a/libcxx/include/__cxx03/__algorithm/max_element.h +++ b/libcxx/include/__cxx03/__algorithm/max_element.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MAX_ELEMENT_H -#define _LIBCPP___ALGORITHM_MAX_ELEMENT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MAX_ELEMENT_H +#define _LIBCPP___CXX03___ALGORITHM_MAX_ELEMENT_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -48,4 +48,4 @@ max_element(_ForwardIterator __first, _ForwardIterator __last) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_MAX_ELEMENT_H +#endif // _LIBCPP___CXX03___ALGORITHM_MAX_ELEMENT_H diff --git a/libcxx/include/__cxx03/__algorithm/merge.h b/libcxx/include/__cxx03/__algorithm/merge.h index 41b0c9263e2fd..90b986f747a3c 100644 --- a/libcxx/include/__cxx03/__algorithm/merge.h +++ b/libcxx/include/__cxx03/__algorithm/merge.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MERGE_H -#define _LIBCPP___ALGORITHM_MERGE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MERGE_H +#define _LIBCPP___CXX03___ALGORITHM_MERGE_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -66,4 +66,4 @@ merge(_InputIterator1 __first1, _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_MERGE_H +#endif // _LIBCPP___CXX03___ALGORITHM_MERGE_H diff --git a/libcxx/include/__cxx03/__algorithm/min.h b/libcxx/include/__cxx03/__algorithm/min.h index 836f8f0028748..d4801ab3330da 100644 --- a/libcxx/include/__cxx03/__algorithm/min.h +++ b/libcxx/include/__cxx03/__algorithm/min.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MIN_H -#define _LIBCPP___ALGORITHM_MIN_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MIN_H +#define _LIBCPP___CXX03___ALGORITHM_MIN_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -55,4 +55,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_MIN_H +#endif // _LIBCPP___CXX03___ALGORITHM_MIN_H diff --git a/libcxx/include/__cxx03/__algorithm/min_element.h b/libcxx/include/__cxx03/__algorithm/min_element.h index d625ab0886cf7..aa4f6013e8752 100644 --- a/libcxx/include/__cxx03/__algorithm/min_element.h +++ b/libcxx/include/__cxx03/__algorithm/min_element.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MIN_ELEMENT_H -#define _LIBCPP___ALGORITHM_MIN_ELEMENT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MIN_ELEMENT_H +#define _LIBCPP___CXX03___ALGORITHM_MIN_ELEMENT_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -68,4 +68,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_MIN_ELEMENT_H +#endif // _LIBCPP___CXX03___ALGORITHM_MIN_ELEMENT_H diff --git a/libcxx/include/__cxx03/__algorithm/min_max_result.h b/libcxx/include/__cxx03/__algorithm/min_max_result.h index 2b56f88f1f9fe..2098aada70a52 100644 --- a/libcxx/include/__cxx03/__algorithm/min_max_result.h +++ b/libcxx/include/__cxx03/__algorithm/min_max_result.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H -#define _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MIN_MAX_RESULT_H +#define _LIBCPP___CXX03___ALGORITHM_MIN_MAX_RESULT_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__config> @@ -53,4 +53,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_MIN_MAX_RESULT_H +#endif // _LIBCPP___CXX03___ALGORITHM_MIN_MAX_RESULT_H diff --git a/libcxx/include/__cxx03/__algorithm/minmax.h b/libcxx/include/__cxx03/__algorithm/minmax.h index a36970a0565fe..e09a5b04104aa 100644 --- a/libcxx/include/__cxx03/__algorithm/minmax.h +++ b/libcxx/include/__cxx03/__algorithm/minmax.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MINMAX_H -#define _LIBCPP___ALGORITHM_MINMAX_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MINMAX_H +#define _LIBCPP___CXX03___ALGORITHM_MINMAX_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/minmax_element.h> @@ -56,4 +56,4 @@ minmax(initializer_list<_Tp> __t) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_MINMAX_H +#endif // _LIBCPP___CXX03___ALGORITHM_MINMAX_H diff --git a/libcxx/include/__cxx03/__algorithm/minmax_element.h b/libcxx/include/__cxx03/__algorithm/minmax_element.h index 6298784092354..673c22020ef3a 100644 --- a/libcxx/include/__cxx03/__algorithm/minmax_element.h +++ b/libcxx/include/__cxx03/__algorithm/minmax_element.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H -#define _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MINMAX_ELEMENT_H +#define _LIBCPP___CXX03___ALGORITHM_MINMAX_ELEMENT_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__config> @@ -97,4 +97,4 @@ minmax_element(_ForwardIterator __first, _ForwardIterator __last) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_MINMAX_ELEMENT_H +#endif // _LIBCPP___CXX03___ALGORITHM_MINMAX_ELEMENT_H diff --git a/libcxx/include/__cxx03/__algorithm/mismatch.h b/libcxx/include/__cxx03/__algorithm/mismatch.h index 1eb9717c9ae6c..163bc8fb165c0 100644 --- a/libcxx/include/__cxx03/__algorithm/mismatch.h +++ b/libcxx/include/__cxx03/__algorithm/mismatch.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MISMATCH_H -#define _LIBCPP___ALGORITHM_MISMATCH_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MISMATCH_H +#define _LIBCPP___CXX03___ALGORITHM_MISMATCH_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/min.h> @@ -214,4 +214,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_MISMATCH_H +#endif // _LIBCPP___CXX03___ALGORITHM_MISMATCH_H diff --git a/libcxx/include/__cxx03/__algorithm/move.h b/libcxx/include/__cxx03/__algorithm/move.h index 11366afe99ffb..cb158e15f19f5 100644 --- a/libcxx/include/__cxx03/__algorithm/move.h +++ b/libcxx/include/__cxx03/__algorithm/move.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MOVE_H -#define _LIBCPP___ALGORITHM_MOVE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MOVE_H +#define _LIBCPP___CXX03___ALGORITHM_MOVE_H #include <__cxx03/__algorithm/copy_move_common.h> #include <__cxx03/__algorithm/for_each_segment.h> @@ -124,4 +124,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_MOVE_H +#endif // _LIBCPP___CXX03___ALGORITHM_MOVE_H diff --git a/libcxx/include/__cxx03/__algorithm/move_backward.h b/libcxx/include/__cxx03/__algorithm/move_backward.h index 9d3e87bb9667e..d4da82382a4c7 100644 --- a/libcxx/include/__cxx03/__algorithm/move_backward.h +++ b/libcxx/include/__cxx03/__algorithm/move_backward.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_MOVE_BACKWARD_H -#define _LIBCPP___ALGORITHM_MOVE_BACKWARD_H +#ifndef _LIBCPP___CXX03___ALGORITHM_MOVE_BACKWARD_H +#define _LIBCPP___CXX03___ALGORITHM_MOVE_BACKWARD_H #include <__cxx03/__algorithm/copy_move_common.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -134,4 +134,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_MOVE_BACKWARD_H +#endif // _LIBCPP___CXX03___ALGORITHM_MOVE_BACKWARD_H diff --git a/libcxx/include/__cxx03/__algorithm/next_permutation.h b/libcxx/include/__cxx03/__algorithm/next_permutation.h index 02aa9113d1830..7d6b2ddad5056 100644 --- a/libcxx/include/__cxx03/__algorithm/next_permutation.h +++ b/libcxx/include/__cxx03/__algorithm/next_permutation.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H -#define _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_NEXT_PERMUTATION_H +#define _LIBCPP___CXX03___ALGORITHM_NEXT_PERMUTATION_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -72,4 +72,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_NEXT_PERMUTATION_H +#endif // _LIBCPP___CXX03___ALGORITHM_NEXT_PERMUTATION_H diff --git a/libcxx/include/__cxx03/__algorithm/none_of.h b/libcxx/include/__cxx03/__algorithm/none_of.h index e5d095da23482..91162ec24ab1d 100644 --- a/libcxx/include/__cxx03/__algorithm/none_of.h +++ b/libcxx/include/__cxx03/__algorithm/none_of.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_NONE_OF_H -#define _LIBCPP___ALGORITHM_NONE_OF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_NONE_OF_H +#define _LIBCPP___CXX03___ALGORITHM_NONE_OF_H #include <__cxx03/__config> @@ -29,4 +29,4 @@ none_of(_InputIterator __first, _InputIterator __last, _Predicate __pred) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_NONE_OF_H +#endif // _LIBCPP___CXX03___ALGORITHM_NONE_OF_H diff --git a/libcxx/include/__cxx03/__algorithm/nth_element.h b/libcxx/include/__cxx03/__algorithm/nth_element.h index f840864c531c5..232966e0d2670 100644 --- a/libcxx/include/__cxx03/__algorithm/nth_element.h +++ b/libcxx/include/__cxx03/__algorithm/nth_element.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_NTH_ELEMENT_H -#define _LIBCPP___ALGORITHM_NTH_ELEMENT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_NTH_ELEMENT_H +#define _LIBCPP___CXX03___ALGORITHM_NTH_ELEMENT_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -258,4 +258,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_NTH_ELEMENT_H +#endif // _LIBCPP___CXX03___ALGORITHM_NTH_ELEMENT_H diff --git a/libcxx/include/__cxx03/__algorithm/partial_sort.h b/libcxx/include/__cxx03/__algorithm/partial_sort.h index 6984b1c91f201..04597fc32b9a2 100644 --- a/libcxx/include/__cxx03/__algorithm/partial_sort.h +++ b/libcxx/include/__cxx03/__algorithm/partial_sort.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_H -#define _LIBCPP___ALGORITHM_PARTIAL_SORT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_PARTIAL_SORT_H +#define _LIBCPP___CXX03___ALGORITHM_PARTIAL_SORT_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -88,4 +88,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_H +#endif // _LIBCPP___CXX03___ALGORITHM_PARTIAL_SORT_H diff --git a/libcxx/include/__cxx03/__algorithm/partial_sort_copy.h b/libcxx/include/__cxx03/__algorithm/partial_sort_copy.h index c8849b9f6175f..d4b5fafba9678 100644 --- a/libcxx/include/__cxx03/__algorithm/partial_sort_copy.h +++ b/libcxx/include/__cxx03/__algorithm/partial_sort_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H -#define _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_PARTIAL_SORT_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_PARTIAL_SORT_COPY_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -103,4 +103,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_PARTIAL_SORT_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_PARTIAL_SORT_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/partition.h b/libcxx/include/__cxx03/__algorithm/partition.h index 5f26384b7c8ef..d39dbbbd0b185 100644 --- a/libcxx/include/__cxx03/__algorithm/partition.h +++ b/libcxx/include/__cxx03/__algorithm/partition.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_PARTITION_H -#define _LIBCPP___ALGORITHM_PARTITION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_PARTITION_H +#define _LIBCPP___CXX03___ALGORITHM_PARTITION_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__config> @@ -87,4 +87,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_PARTITION_H +#endif // _LIBCPP___CXX03___ALGORITHM_PARTITION_H diff --git a/libcxx/include/__cxx03/__algorithm/partition_copy.h b/libcxx/include/__cxx03/__algorithm/partition_copy.h index 916a1c301d6d5..18d82cfa20326 100644 --- a/libcxx/include/__cxx03/__algorithm/partition_copy.h +++ b/libcxx/include/__cxx03/__algorithm/partition_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_PARTITION_COPY_H -#define _LIBCPP___ALGORITHM_PARTITION_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_PARTITION_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_PARTITION_COPY_H #include <__cxx03/__config> #include <__cxx03/__iterator/iterator_traits.h> @@ -40,4 +40,4 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 pair<_OutputIterator1, _Outp _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_PARTITION_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_PARTITION_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/partition_point.h b/libcxx/include/__cxx03/__algorithm/partition_point.h index c28ee8cae0e6d..ccf203bbf245e 100644 --- a/libcxx/include/__cxx03/__algorithm/partition_point.h +++ b/libcxx/include/__cxx03/__algorithm/partition_point.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_PARTITION_POINT_H -#define _LIBCPP___ALGORITHM_PARTITION_POINT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_PARTITION_POINT_H +#define _LIBCPP___CXX03___ALGORITHM_PARTITION_POINT_H #include <__cxx03/__algorithm/half_positive.h> #include <__cxx03/__config> @@ -41,4 +41,4 @@ partition_point(_ForwardIterator __first, _ForwardIterator __last, _Predicate __ _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_PARTITION_POINT_H +#endif // _LIBCPP___CXX03___ALGORITHM_PARTITION_POINT_H diff --git a/libcxx/include/__cxx03/__algorithm/pop_heap.h b/libcxx/include/__cxx03/__algorithm/pop_heap.h index 800cabf94eaa9..5d19e902ff13b 100644 --- a/libcxx/include/__cxx03/__algorithm/pop_heap.h +++ b/libcxx/include/__cxx03/__algorithm/pop_heap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_POP_HEAP_H -#define _LIBCPP___ALGORITHM_POP_HEAP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_POP_HEAP_H +#define _LIBCPP___CXX03___ALGORITHM_POP_HEAP_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -78,4 +78,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_POP_HEAP_H +#endif // _LIBCPP___CXX03___ALGORITHM_POP_HEAP_H diff --git a/libcxx/include/__cxx03/__algorithm/prev_permutation.h b/libcxx/include/__cxx03/__algorithm/prev_permutation.h index 2569156eac642..b050d9cf337a7 100644 --- a/libcxx/include/__cxx03/__algorithm/prev_permutation.h +++ b/libcxx/include/__cxx03/__algorithm/prev_permutation.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_PREV_PERMUTATION_H -#define _LIBCPP___ALGORITHM_PREV_PERMUTATION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_PREV_PERMUTATION_H +#define _LIBCPP___CXX03___ALGORITHM_PREV_PERMUTATION_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -72,4 +72,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_PREV_PERMUTATION_H +#endif // _LIBCPP___CXX03___ALGORITHM_PREV_PERMUTATION_H diff --git a/libcxx/include/__cxx03/__algorithm/pstl.h b/libcxx/include/__cxx03/__algorithm/pstl.h index 8dea15e09cb44..4fc0d47996107 100644 --- a/libcxx/include/__cxx03/__algorithm/pstl.h +++ b/libcxx/include/__cxx03/__algorithm/pstl.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_PSTL_H -#define _LIBCPP___ALGORITHM_PSTL_H +#ifndef _LIBCPP___CXX03___ALGORITHM_PSTL_H +#define _LIBCPP___CXX03___ALGORITHM_PSTL_H #include <__cxx03/__config> @@ -660,4 +660,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_PSTL_H +#endif // _LIBCPP___CXX03___ALGORITHM_PSTL_H diff --git a/libcxx/include/__cxx03/__algorithm/push_heap.h b/libcxx/include/__cxx03/__algorithm/push_heap.h index de4dcc33fb1fd..9ef44cdb3feea 100644 --- a/libcxx/include/__cxx03/__algorithm/push_heap.h +++ b/libcxx/include/__cxx03/__algorithm/push_heap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_PUSH_HEAP_H -#define _LIBCPP___ALGORITHM_PUSH_HEAP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_PUSH_HEAP_H +#define _LIBCPP___CXX03___ALGORITHM_PUSH_HEAP_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -81,4 +81,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_PUSH_HEAP_H +#endif // _LIBCPP___CXX03___ALGORITHM_PUSH_HEAP_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_adjacent_find.h b/libcxx/include/__cxx03/__algorithm/ranges_adjacent_find.h index 26caf4fe40ae0..e62db90f83c18 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_adjacent_find.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_adjacent_find.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H -#define _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_ADJACENT_FIND_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_ADJACENT_FIND_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -80,4 +80,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_ADJACENT_FIND_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_ADJACENT_FIND_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_all_of.h b/libcxx/include/__cxx03/__algorithm/ranges_all_of.h index 7e92c37b8fd99..e03f48b23c222 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_all_of.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_all_of.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_ALL_OF_H -#define _LIBCPP___ALGORITHM_RANGES_ALL_OF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_ALL_OF_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_ALL_OF_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -71,4 +71,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_ALL_OF_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_ALL_OF_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_any_of.h b/libcxx/include/__cxx03/__algorithm/ranges_any_of.h index d20177223fc6b..23b21f9a8bf13 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_any_of.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_any_of.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_ANY_OF_H -#define _LIBCPP___ALGORITHM_RANGES_ANY_OF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_ANY_OF_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_ANY_OF_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -71,4 +71,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_ANY_OF_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_ANY_OF_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_binary_search.h b/libcxx/include/__cxx03/__algorithm/ranges_binary_search.h index 675cc1ac8074a..18ebf2b07bdb6 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_binary_search.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_binary_search.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H -#define _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_BINARY_SEARCH_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_BINARY_SEARCH_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/lower_bound.h> @@ -70,4 +70,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_BINARY_SEARCH_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_BINARY_SEARCH_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_clamp.h b/libcxx/include/__cxx03/__algorithm/ranges_clamp.h index 3f9f6b1f9944f..da4dda06a2255 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_clamp.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_clamp.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_CLAMP_H -#define _LIBCPP___ALGORITHM_RANGES_CLAMP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_CLAMP_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_CLAMP_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -63,4 +63,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_CLAMP_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_CLAMP_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_contains.h b/libcxx/include/__cxx03/__algorithm/ranges_contains.h index 312de975efa5f..00b9d08c83c6c 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_contains.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_contains.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_CONTAINS_H -#define _LIBCPP___ALGORITHM_RANGES_CONTAINS_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_CONTAINS_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_CONTAINS_H #include <__cxx03/__algorithm/ranges_find.h> #include <__cxx03/__config> @@ -63,4 +63,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_CONTAINS_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_CONTAINS_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_contains_subrange.h b/libcxx/include/__cxx03/__algorithm/ranges_contains_subrange.h index d3302f1c915df..6ac67b43ca6cc 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_contains_subrange.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_contains_subrange.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H -#define _LIBCPP___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H #include <__cxx03/__algorithm/ranges_search.h> #include <__cxx03/__config> @@ -94,4 +94,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_CONTAINS_SUBRANGE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_copy.h b/libcxx/include/__cxx03/__algorithm/ranges_copy.h index cf3f9974936ad..e94a2089a692c 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_copy.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_H -#define _LIBCPP___ALGORITHM_RANGES_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_COPY_H #include <__cxx03/__algorithm/copy.h> #include <__cxx03/__algorithm/in_out_result.h> @@ -68,4 +68,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_copy_backward.h b/libcxx/include/__cxx03/__algorithm/ranges_copy_backward.h index a6bb781397dec..90928177491f5 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_copy_backward.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_copy_backward.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H -#define _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_COPY_BACKWARD_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_COPY_BACKWARD_H #include <__cxx03/__algorithm/copy_backward.h> #include <__cxx03/__algorithm/in_out_result.h> @@ -66,4 +66,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_COPY_BACKWARD_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_COPY_BACKWARD_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_copy_if.h b/libcxx/include/__cxx03/__algorithm/ranges_copy_if.h index f0d3005a4982b..814d408cb703e 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_copy_if.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_copy_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_IF_H -#define _LIBCPP___ALGORITHM_RANGES_COPY_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_COPY_IF_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_COPY_IF_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__config> @@ -84,4 +84,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_COPY_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_COPY_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_copy_n.h b/libcxx/include/__cxx03/__algorithm/ranges_copy_n.h index 92f10e7466e53..67639e7c19aff 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_copy_n.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_copy_n.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_COPY_N_H -#define _LIBCPP___ALGORITHM_RANGES_COPY_N_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_COPY_N_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_COPY_N_H #include <__cxx03/__algorithm/copy.h> #include <__cxx03/__algorithm/in_out_result.h> @@ -78,4 +78,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_COPY_N_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_COPY_N_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_count.h b/libcxx/include/__cxx03/__algorithm/ranges_count.h index ae24b57c17d0a..b8553badfce02 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_count.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_count.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_COUNT_H -#define _LIBCPP___ALGORITHM_RANGES_COUNT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_COUNT_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_COUNT_H #include <__cxx03/__algorithm/count.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -63,4 +63,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_COUNT_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_count_if.h b/libcxx/include/__cxx03/__algorithm/ranges_count_if.h index ecadf6fac7128..10850c857d6df 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_count_if.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_count_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H -#define _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_COUNT_IF_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_COUNT_IF_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -76,4 +76,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_COUNT_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_COUNT_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_ends_with.h b/libcxx/include/__cxx03/__algorithm/ranges_ends_with.h index 85329f8f4e58a..39dcb79559c22 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_ends_with.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_ends_with.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_ENDS_WITH_H -#define _LIBCPP___ALGORITHM_RANGES_ENDS_WITH_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_ENDS_WITH_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_ENDS_WITH_H #include <__cxx03/__algorithm/ranges_equal.h> #include <__cxx03/__algorithm/ranges_starts_with.h> @@ -198,4 +198,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_ENDS_WITH_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_ENDS_WITH_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_equal.h b/libcxx/include/__cxx03/__algorithm/ranges_equal.h index b89235a299414..abc701a9f1188 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_equal.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_equal.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_EQUAL_H -#define _LIBCPP___ALGORITHM_RANGES_EQUAL_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_EQUAL_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_EQUAL_H #include <__cxx03/__algorithm/equal.h> #include <__cxx03/__algorithm/unwrap_range.h> @@ -106,4 +106,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_EQUAL_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_equal_range.h b/libcxx/include/__cxx03/__algorithm/ranges_equal_range.h index d6a38e5edd312..64e686704efd2 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_equal_range.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_equal_range.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H -#define _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_EQUAL_RANGE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_EQUAL_RANGE_H #include <__cxx03/__algorithm/equal_range.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -77,4 +77,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_EQUAL_RANGE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_EQUAL_RANGE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_fill.h b/libcxx/include/__cxx03/__algorithm/ranges_fill.h index 56008ec7304da..f85a1f4ed21c1 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_fill.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_fill.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_FILL_H -#define _LIBCPP___ALGORITHM_RANGES_FILL_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_FILL_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_FILL_H #include <__cxx03/__algorithm/ranges_fill_n.h> #include <__cxx03/__config> @@ -59,4 +59,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_FILL_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_FILL_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_fill_n.h b/libcxx/include/__cxx03/__algorithm/ranges_fill_n.h index bb00676943a6c..07f04c293451f 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_fill_n.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_fill_n.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_FILL_N_H -#define _LIBCPP___ALGORITHM_RANGES_FILL_N_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_FILL_N_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_FILL_N_H #include <__cxx03/__config> #include <__cxx03/__iterator/concepts.h> @@ -50,4 +50,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_FILL_N_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_FILL_N_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_find.h b/libcxx/include/__cxx03/__algorithm/ranges_find.h index 896fe920fd815..0b2c865476db0 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_find.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_find.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_H -#define _LIBCPP___ALGORITHM_RANGES_FIND_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_H #include <__cxx03/__algorithm/find.h> #include <__cxx03/__algorithm/ranges_find_if.h> @@ -77,4 +77,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_FIND_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_find_end.h b/libcxx/include/__cxx03/__algorithm/ranges_find_end.h index c71f32546afb1..117753b3d86b6 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_find_end.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_find_end.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_END_H -#define _LIBCPP___ALGORITHM_RANGES_FIND_END_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_END_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_END_H #include <__cxx03/__algorithm/find_end.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -100,4 +100,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_FIND_END_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_END_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_find_first_of.h b/libcxx/include/__cxx03/__algorithm/ranges_find_first_of.h index 23ae82eb4685f..ebf01681419ca 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_find_first_of.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_find_first_of.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H -#define _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_FIRST_OF_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_FIRST_OF_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -103,4 +103,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_FIND_FIRST_OF_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_FIRST_OF_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_find_if.h b/libcxx/include/__cxx03/__algorithm/ranges_find_if.h index a518f532a73e2..a1098e0de1824 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_find_if.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_find_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_IF_H -#define _LIBCPP___ALGORITHM_RANGES_FIND_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_IF_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_IF_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -72,4 +72,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_find_if_not.h b/libcxx/include/__cxx03/__algorithm/ranges_find_if_not.h index c54d565188c4f..6bc8f16395873 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_find_if_not.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_find_if_not.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H -#define _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_IF_NOT_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_IF_NOT_H #include <__cxx03/__algorithm/ranges_find_if.h> #include <__cxx03/__config> @@ -66,4 +66,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_FIND_IF_NOT_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_IF_NOT_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_find_last.h b/libcxx/include/__cxx03/__algorithm/ranges_find_last.h index 3028dc5bf53cb..506452c7c001d 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_find_last.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_find_last.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H -#define _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_LAST_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_LAST_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -172,4 +172,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_FIND_LAST_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_FIND_LAST_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_for_each.h b/libcxx/include/__cxx03/__algorithm/ranges_for_each.h index eca0f35e49fbd..3e926e9d2c4d1 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_for_each.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_for_each.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H -#define _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_FOR_EACH_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_FOR_EACH_H #include <__cxx03/__algorithm/in_fun_result.h> #include <__cxx03/__config> @@ -78,4 +78,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_FOR_EACH_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_for_each_n.h b/libcxx/include/__cxx03/__algorithm/ranges_for_each_n.h index fa3051fa8a0aa..96df211298541 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_for_each_n.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_for_each_n.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H -#define _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_FOR_EACH_N_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_FOR_EACH_N_H #include <__cxx03/__algorithm/in_fun_result.h> #include <__cxx03/__config> @@ -61,4 +61,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_FOR_EACH_N_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_FOR_EACH_N_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_generate.h b/libcxx/include/__cxx03/__algorithm/ranges_generate.h index 570ed73a29550..96d43592d2a76 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_generate.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_generate.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_GENERATE_H -#define _LIBCPP___ALGORITHM_RANGES_GENERATE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_GENERATE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_GENERATE_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__concepts/invocable.h> @@ -70,4 +70,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_GENERATE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_generate_n.h b/libcxx/include/__cxx03/__algorithm/ranges_generate_n.h index b7c684be2e03f..dd43e21618718 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_generate_n.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_generate_n.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H -#define _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_GENERATE_N_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_GENERATE_N_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__concepts/invocable.h> @@ -62,4 +62,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_GENERATE_N_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_GENERATE_N_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_includes.h b/libcxx/include/__cxx03/__algorithm/ranges_includes.h index 3abe69118f20a..587a0eda16da5 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_includes.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_includes.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_INCLUDES_H -#define _LIBCPP___ALGORITHM_RANGES_INCLUDES_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_INCLUDES_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_INCLUDES_H #include <__cxx03/__algorithm/includes.h> #include <__cxx03/__algorithm/make_projected.h> @@ -95,4 +95,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_INCLUDES_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_INCLUDES_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_inplace_merge.h b/libcxx/include/__cxx03/__algorithm/ranges_inplace_merge.h index ebb711d731209..34668f4d57baf 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_inplace_merge.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_inplace_merge.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H -#define _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_INPLACE_MERGE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_INPLACE_MERGE_H #include <__cxx03/__algorithm/inplace_merge.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -81,4 +81,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_INPLACE_MERGE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_INPLACE_MERGE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_is_heap.h b/libcxx/include/__cxx03/__algorithm/ranges_is_heap.h index 7c6b60a56f6c7..47112bdddd057 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_is_heap.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_is_heap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H -#define _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_IS_HEAP_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_IS_HEAP_H #include <__cxx03/__algorithm/is_heap_until.h> #include <__cxx03/__algorithm/make_projected.h> @@ -78,4 +78,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_IS_HEAP_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_is_heap_until.h b/libcxx/include/__cxx03/__algorithm/ranges_is_heap_until.h index e32e802f44732..d7176f784037c 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_is_heap_until.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_is_heap_until.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H -#define _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_IS_HEAP_UNTIL_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_IS_HEAP_UNTIL_H #include <__cxx03/__algorithm/is_heap_until.h> #include <__cxx03/__algorithm/make_projected.h> @@ -78,4 +78,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_IS_HEAP_UNTIL_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_IS_HEAP_UNTIL_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_is_partitioned.h b/libcxx/include/__cxx03/__algorithm/ranges_is_partitioned.h index 87d59d0410fe5..d746f55322e78 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_is_partitioned.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_is_partitioned.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H -#define _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_IS_PARTITIONED_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_IS_PARTITIONED_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -83,4 +83,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_IS_PARTITIONED_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_IS_PARTITIONED_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_is_permutation.h b/libcxx/include/__cxx03/__algorithm/ranges_is_permutation.h index a894854a8b65a..31d85e5fb27cd 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_is_permutation.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_is_permutation.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H -#define _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_IS_PERMUTATION_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_IS_PERMUTATION_H #include <__cxx03/__algorithm/is_permutation.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -104,4 +104,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_IS_PERMUTATION_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_IS_PERMUTATION_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_is_sorted.h b/libcxx/include/__cxx03/__algorithm/ranges_is_sorted.h index 201673553fd4f..f5c4e6f4191ad 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_is_sorted.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_is_sorted.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H -#define _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H +#ifndef _LIBCPP___CXX03__ALGORITHM_RANGES_IS_SORTED_H +#define _LIBCPP___CXX03__ALGORITHM_RANGES_IS_SORTED_H #include <__cxx03/__algorithm/ranges_is_sorted_until.h> #include <__cxx03/__config> @@ -64,4 +64,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_H +#endif // _LIBCPP___CXX03__ALGORITHM_RANGES_IS_SORTED_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_is_sorted_until.h b/libcxx/include/__cxx03/__algorithm/ranges_is_sorted_until.h index 713d2664884ac..701c01749c260 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_is_sorted_until.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_is_sorted_until.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H -#define _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H +#ifndef _LIBCPP___CXX03__ALGORITHM_RANGES_IS_SORTED_UNTIL_H +#define _LIBCPP___CXX03__ALGORITHM_RANGES_IS_SORTED_UNTIL_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -79,4 +79,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP__ALGORITHM_RANGES_IS_SORTED_UNTIL_H +#endif // _LIBCPP___CXX03__ALGORITHM_RANGES_IS_SORTED_UNTIL_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_iterator_concept.h b/libcxx/include/__cxx03/__algorithm/ranges_iterator_concept.h index eb2025c234ba1..1ff6328cfc150 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_iterator_concept.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_iterator_concept.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H -#define _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_ITERATOR_CONCEPT_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_ITERATOR_CONCEPT_H #include <__cxx03/__config> #include <__cxx03/__iterator/concepts.h> @@ -53,4 +53,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_ITERATOR_CONCEPT_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_ITERATOR_CONCEPT_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_lexicographical_compare.h b/libcxx/include/__cxx03/__algorithm/ranges_lexicographical_compare.h index ba87a20b425b4..e3fec1c416519 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_lexicographical_compare.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_lexicographical_compare.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H -#define _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -103,4 +103,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_LEXICOGRAPHICAL_COMPARE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_lower_bound.h b/libcxx/include/__cxx03/__algorithm/ranges_lower_bound.h index 2c312866ee930..bed4c815e5b4f 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_lower_bound.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_lower_bound.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H -#define _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_LOWER_BOUND_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_LOWER_BOUND_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/lower_bound.h> @@ -70,4 +70,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_LOWER_BOUND_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_LOWER_BOUND_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_make_heap.h b/libcxx/include/__cxx03/__algorithm/ranges_make_heap.h index 5a00575abbd34..ba8ccb89baad6 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_make_heap.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_make_heap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H -#define _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_MAKE_HEAP_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_MAKE_HEAP_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/make_heap.h> @@ -82,4 +82,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_MAKE_HEAP_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_MAKE_HEAP_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_max.h b/libcxx/include/__cxx03/__algorithm/ranges_max.h index d61a54fa7fff7..58ea541d3e493 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_max.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_max.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_MAX_H -#define _LIBCPP___ALGORITHM_RANGES_MAX_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_MAX_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_MAX_H #include <__cxx03/__algorithm/ranges_min_element.h> #include <__cxx03/__assert> @@ -100,4 +100,4 @@ _LIBCPP_POP_MACROS #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___ALGORITHM_RANGES_MAX_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_MAX_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_max_element.h b/libcxx/include/__cxx03/__algorithm/ranges_max_element.h index 6bcf77bc29d4d..cbe50d1bf4127 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_max_element.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_max_element.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H -#define _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_MAX_ELEMENT_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_MAX_ELEMENT_H #include <__cxx03/__algorithm/ranges_min_element.h> #include <__cxx03/__config> @@ -66,4 +66,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_MAX_ELEMENT_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_MAX_ELEMENT_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_merge.h b/libcxx/include/__cxx03/__algorithm/ranges_merge.h index 697dfdae0b300..8b8b8fbbab2cb 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_merge.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_merge.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_MERGE_H -#define _LIBCPP___ALGORITHM_RANGES_MERGE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_MERGE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_MERGE_H #include <__cxx03/__algorithm/in_in_out_result.h> #include <__cxx03/__algorithm/ranges_copy.h> @@ -135,4 +135,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_MERGE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_MERGE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_min.h b/libcxx/include/__cxx03/__algorithm/ranges_min.h index bcf0705071318..72f06e72e3003 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_min.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_min.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_MIN_H -#define _LIBCPP___ALGORITHM_RANGES_MIN_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_MIN_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_MIN_H #include <__cxx03/__algorithm/ranges_min_element.h> #include <__cxx03/__assert> @@ -92,4 +92,4 @@ _LIBCPP_POP_MACROS #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___ALGORITHM_RANGES_MIN_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_MIN_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_min_element.h b/libcxx/include/__cxx03/__algorithm/ranges_min_element.h index 320a47a57ec6d..b3854233966b0 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_min_element.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_min_element.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H -#define _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_MIN_ELEMENT_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_MIN_ELEMENT_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -78,4 +78,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_MIN_ELEMENT_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_MIN_ELEMENT_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_minmax.h b/libcxx/include/__cxx03/__algorithm/ranges_minmax.h index 8adf1af585518..8ce4e438382e5 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_minmax.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_minmax.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_MINMAX_H -#define _LIBCPP___ALGORITHM_RANGES_MINMAX_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_MINMAX_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_MINMAX_H #include <__cxx03/__algorithm/min_max_result.h> #include <__cxx03/__algorithm/minmax_element.h> @@ -172,4 +172,4 @@ _LIBCPP_POP_MACROS #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_MINMAX_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_minmax_element.h b/libcxx/include/__cxx03/__algorithm/ranges_minmax_element.h index ebc44082f4c3a..1e92a63a9d33e 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_minmax_element.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_minmax_element.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_MINMAX_ELEMENT_H -#define _LIBCPP___ALGORITHM_RANGES_MINMAX_ELEMENT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_MINMAX_ELEMENT_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_MINMAX_ELEMENT_H #include <__cxx03/__algorithm/min_max_result.h> #include <__cxx03/__algorithm/minmax_element.h> @@ -75,4 +75,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_MINMAX_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_MINMAX_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_mismatch.h b/libcxx/include/__cxx03/__algorithm/ranges_mismatch.h index ccca6c7f6eb55..d3ebb7ded9c0b 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_mismatch.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_mismatch.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_MISMATCH_H -#define _LIBCPP___ALGORITHM_RANGES_MISMATCH_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_MISMATCH_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_MISMATCH_H #include <__cxx03/__algorithm/in_in_result.h> #include <__cxx03/__algorithm/mismatch.h> @@ -97,4 +97,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_MISMATCH_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_MISMATCH_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_move.h b/libcxx/include/__cxx03/__algorithm/ranges_move.h index 452608bef7456..e20f4d8854db2 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_move.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_move.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_MOVE_H -#define _LIBCPP___ALGORITHM_RANGES_MOVE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_MOVE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_MOVE_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -71,4 +71,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_MOVE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_MOVE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_move_backward.h b/libcxx/include/__cxx03/__algorithm/ranges_move_backward.h index e353d9e2ffd10..cecaa7d8d657b 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_move_backward.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_move_backward.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H -#define _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_MOVE_BACKWARD_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_MOVE_BACKWARD_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -73,4 +73,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_MOVE_BACKWARD_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_MOVE_BACKWARD_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_next_permutation.h b/libcxx/include/__cxx03/__algorithm/ranges_next_permutation.h index b134cfca38195..337c7a892cfba 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_next_permutation.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_next_permutation.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H -#define _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_NEXT_PERMUTATION_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_NEXT_PERMUTATION_H #include <__cxx03/__algorithm/in_found_result.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -75,4 +75,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_NEXT_PERMUTATION_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_NEXT_PERMUTATION_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_none_of.h b/libcxx/include/__cxx03/__algorithm/ranges_none_of.h index 36d5477e14dee..461fbc87c5d24 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_none_of.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_none_of.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_NONE_OF_H -#define _LIBCPP___ALGORITHM_RANGES_NONE_OF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_NONE_OF_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_NONE_OF_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -72,4 +72,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_NONE_OF_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_NONE_OF_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_nth_element.h b/libcxx/include/__cxx03/__algorithm/ranges_nth_element.h index df428390f7a3d..27bf33e7703de 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_nth_element.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_nth_element.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H -#define _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_NTH_ELEMENT_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_NTH_ELEMENT_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/make_projected.h> @@ -81,4 +81,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_NTH_ELEMENT_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_NTH_ELEMENT_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_partial_sort.h b/libcxx/include/__cxx03/__algorithm/ranges_partial_sort.h index d19fc9b5297eb..06aab77f65f3c 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_partial_sort.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_partial_sort.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H -#define _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_PARTIAL_SORT_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_PARTIAL_SORT_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/make_projected.h> @@ -79,4 +79,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_PARTIAL_SORT_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_partial_sort_copy.h b/libcxx/include/__cxx03/__algorithm/ranges_partial_sort_copy.h index bd2be3cb2cf2d..3fda0e58e74d0 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_partial_sort_copy.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_partial_sort_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H -#define _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -111,4 +111,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_PARTIAL_SORT_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_partition.h b/libcxx/include/__cxx03/__algorithm/ranges_partition.h index d6c147c441def..261972ada5683 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_partition.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_partition.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_PARTITION_H -#define _LIBCPP___ALGORITHM_RANGES_PARTITION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_PARTITION_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_PARTITION_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/make_projected.h> @@ -85,4 +85,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_PARTITION_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_partition_copy.h b/libcxx/include/__cxx03/__algorithm/ranges_partition_copy.h index 42cbb3a96a237..c80108022d096 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_partition_copy.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_partition_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H -#define _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_PARTITION_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_PARTITION_COPY_H #include <__cxx03/__algorithm/in_out_out_result.h> #include <__cxx03/__config> @@ -107,4 +107,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_PARTITION_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_partition_point.h b/libcxx/include/__cxx03/__algorithm/ranges_partition_point.h index 60731b2ddcf3c..337e1261f01c5 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_partition_point.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_partition_point.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H -#define _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_PARTITION_POINT_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_PARTITION_POINT_H #include <__cxx03/__algorithm/half_positive.h> #include <__cxx03/__config> @@ -90,4 +90,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_PARTITION_POINT_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_PARTITION_POINT_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_pop_heap.h b/libcxx/include/__cxx03/__algorithm/ranges_pop_heap.h index d201d62c73575..ecbfb44888edf 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_pop_heap.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_pop_heap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H -#define _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_POP_HEAP_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_POP_HEAP_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/make_projected.h> @@ -83,4 +83,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_POP_HEAP_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_POP_HEAP_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_prev_permutation.h b/libcxx/include/__cxx03/__algorithm/ranges_prev_permutation.h index 8d40d44e6ac1e..ded9eb2c47155 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_prev_permutation.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_prev_permutation.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H -#define _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_PREV_PERMUTATION_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_PREV_PERMUTATION_H #include <__cxx03/__algorithm/in_found_result.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -75,4 +75,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_PREV_PERMUTATION_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_PREV_PERMUTATION_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_push_heap.h b/libcxx/include/__cxx03/__algorithm/ranges_push_heap.h index 39d219e763dee..33479d9bfad66 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_push_heap.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_push_heap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H -#define _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_PUSH_HEAP_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_PUSH_HEAP_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/make_projected.h> @@ -82,4 +82,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_PUSH_HEAP_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_PUSH_HEAP_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_remove.h b/libcxx/include/__cxx03/__algorithm/ranges_remove.h index d766a7b4a846f..13b4efb9f5c3b 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_remove.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_remove.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_H -#define _LIBCPP___ALGORITHM_RANGES_REMOVE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_REMOVE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_REMOVE_H #include <__cxx03/__config> #include <__cxx03/__algorithm/ranges_remove_if.h> @@ -65,4 +65,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_REMOVE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_remove_copy.h b/libcxx/include/__cxx03/__algorithm/ranges_remove_copy.h index fdb04cd96cf89..47c2d6c086920 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_remove_copy.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_remove_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H -#define _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_REMOVE_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_REMOVE_COPY_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__algorithm/ranges_remove_copy_if.h> @@ -78,4 +78,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_REMOVE_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_remove_copy_if.h b/libcxx/include/__cxx03/__algorithm/ranges_remove_copy_if.h index dd643a581a1d2..3674e4c4207b7 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_remove_copy_if.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_remove_copy_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H -#define _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_REMOVE_COPY_IF_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_REMOVE_COPY_IF_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__algorithm/make_projected.h> @@ -92,4 +92,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_COPY_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_REMOVE_COPY_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_remove_if.h b/libcxx/include/__cxx03/__algorithm/ranges_remove_if.h index 9d4ccd0f0b52d..546acf8b78da3 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_remove_if.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_remove_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H -#define _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_REMOVE_IF_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_REMOVE_IF_H #include <__cxx03/__config> #include <__cxx03/__algorithm/ranges_find_if.h> @@ -86,4 +86,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_REMOVE_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_REMOVE_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_replace.h b/libcxx/include/__cxx03/__algorithm/ranges_replace.h index 774d7632e41cf..f5c030e7993c2 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_replace.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_replace.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_REPLACE_H -#define _LIBCPP___ALGORITHM_RANGES_REPLACE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_REPLACE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_REPLACE_H #include <__cxx03/__algorithm/ranges_replace_if.h> #include <__cxx03/__config> @@ -65,4 +65,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_REPLACE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_replace_copy.h b/libcxx/include/__cxx03/__algorithm/ranges_replace_copy.h index d90715d3661ba..387b7a42f24c8 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_replace_copy.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_replace_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H -#define _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_REPLACE_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_REPLACE_COPY_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__algorithm/ranges_replace_copy_if.h> @@ -90,4 +90,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_REPLACE_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_replace_copy_if.h b/libcxx/include/__cxx03/__algorithm/ranges_replace_copy_if.h index 88e5ff71c58c5..f5786d9f8948d 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_replace_copy_if.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_replace_copy_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H -#define _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_REPLACE_COPY_IF_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_REPLACE_COPY_IF_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__config> @@ -95,4 +95,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_COPY_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_REPLACE_COPY_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_replace_if.h b/libcxx/include/__cxx03/__algorithm/ranges_replace_if.h index 6d9ff45a59c97..499cc7887b16c 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_replace_if.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_replace_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H -#define _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_REPLACE_IF_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_REPLACE_IF_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -78,4 +78,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_REPLACE_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_REPLACE_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_reverse.h b/libcxx/include/__cxx03/__algorithm/ranges_reverse.h index 78614666200ef..577a4310f2152 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_reverse.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_reverse.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_REVERSE_H -#define _LIBCPP___ALGORITHM_RANGES_REVERSE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_REVERSE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_REVERSE_H #include <__cxx03/__config> #include <__cxx03/__iterator/concepts.h> @@ -76,4 +76,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_REVERSE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_reverse_copy.h b/libcxx/include/__cxx03/__algorithm/ranges_reverse_copy.h index 7aab06d721430..d727202365b08 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_reverse_copy.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_reverse_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H -#define _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_REVERSE_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_REVERSE_COPY_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__algorithm/ranges_copy.h> @@ -67,4 +67,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_REVERSE_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_REVERSE_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_rotate.h b/libcxx/include/__cxx03/__algorithm/ranges_rotate.h index 2efa88748ff70..e6bef76b3cb74 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_rotate.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_rotate.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_ROTATE_H -#define _LIBCPP___ALGORITHM_RANGES_ROTATE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_ROTATE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_ROTATE_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/ranges_iterator_concept.h> @@ -68,4 +68,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_ROTATE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_rotate_copy.h b/libcxx/include/__cxx03/__algorithm/ranges_rotate_copy.h index 7aa1fa13feddd..40975ad7213de 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_rotate_copy.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_rotate_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H -#define _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_ROTATE_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_ROTATE_COPY_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__algorithm/ranges_copy.h> @@ -65,4 +65,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_ROTATE_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_ROTATE_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_sample.h b/libcxx/include/__cxx03/__algorithm/ranges_sample.h index 08a44d3a3c855..778661c2ce413 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_sample.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_sample.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_SAMPLE_H -#define _LIBCPP___ALGORITHM_RANGES_SAMPLE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_SAMPLE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_SAMPLE_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/sample.h> @@ -71,4 +71,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_SAMPLE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_SAMPLE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_search.h b/libcxx/include/__cxx03/__algorithm/ranges_search.h index 68ac1fce9e7bf..a4d56b80c9452 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_search.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_search.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_SEARCH_H -#define _LIBCPP___ALGORITHM_RANGES_SEARCH_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_SEARCH_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_SEARCH_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/search.h> @@ -131,4 +131,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_SEARCH_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_search_n.h b/libcxx/include/__cxx03/__algorithm/ranges_search_n.h index c7c670f02c20c..eac6e33a4da9e 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_search_n.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_search_n.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H -#define _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_SEARCH_N_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_SEARCH_N_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/search_n.h> @@ -113,4 +113,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_SEARCH_N_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_SEARCH_N_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_set_difference.h b/libcxx/include/__cxx03/__algorithm/ranges_set_difference.h index 764384b970833..0343b68f8534d 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_set_difference.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_set_difference.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H -#define _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_SET_DIFFERENCE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_SET_DIFFERENCE_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -106,4 +106,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_SET_DIFFERENCE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_SET_DIFFERENCE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_set_intersection.h b/libcxx/include/__cxx03/__algorithm/ranges_set_intersection.h index 4aebb5e195da2..ff0ae0fe1446f 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_set_intersection.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_set_intersection.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H -#define _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_SET_INTERSECTION_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_SET_INTERSECTION_H #include <__cxx03/__algorithm/in_in_out_result.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -111,4 +111,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_SET_INTERSECTION_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_SET_INTERSECTION_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_set_symmetric_difference.h b/libcxx/include/__cxx03/__algorithm/ranges_set_symmetric_difference.h index 50ec574fcc301..4c7413d5a656a 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_set_symmetric_difference.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_set_symmetric_difference.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H -#define _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H #include <__cxx03/__algorithm/in_in_out_result.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -111,4 +111,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_SET_SYMMETRIC_DIFFERENCE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_set_union.h b/libcxx/include/__cxx03/__algorithm/ranges_set_union.h index 87d08e4cfedcc..0752ee51d37d1 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_set_union.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_set_union.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_SET_UNION_H -#define _LIBCPP___ALGORITHM_RANGES_SET_UNION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_SET_UNION_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_SET_UNION_H #include <__cxx03/__algorithm/in_in_out_result.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -112,4 +112,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_SET_UNION_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_SET_UNION_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_shuffle.h b/libcxx/include/__cxx03/__algorithm/ranges_shuffle.h index 44e3a73e1b4b7..2728d5df97f58 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_shuffle.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_shuffle.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H -#define _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_SHUFFLE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_SHUFFLE_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/shuffle.h> @@ -69,4 +69,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_SHUFFLE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_SHUFFLE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_sort.h b/libcxx/include/__cxx03/__algorithm/ranges_sort.h index ad24cea344e8b..4fa26ad238fa1 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_sort.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_sort.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_SORT_H -#define _LIBCPP___ALGORITHM_RANGES_SORT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_SORT_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_SORT_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/make_projected.h> @@ -81,4 +81,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_SORT_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_SORT_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_sort_heap.h b/libcxx/include/__cxx03/__algorithm/ranges_sort_heap.h index 403917b032ddc..7c45fca156bae 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_sort_heap.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_sort_heap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H -#define _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_SORT_HEAP_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_SORT_HEAP_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/make_projected.h> @@ -82,4 +82,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_SORT_HEAP_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_SORT_HEAP_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_stable_partition.h b/libcxx/include/__cxx03/__algorithm/ranges_stable_partition.h index cd4ae07bf9c70..b7d84dc6a0ccb 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_stable_partition.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_stable_partition.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H -#define _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_STABLE_PARTITION_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_STABLE_PARTITION_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/make_projected.h> @@ -89,4 +89,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_STABLE_PARTITION_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_STABLE_PARTITION_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_stable_sort.h b/libcxx/include/__cxx03/__algorithm/ranges_stable_sort.h index 20c83283b9606..83ff06971d081 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_stable_sort.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_stable_sort.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H -#define _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_STABLE_SORT_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_STABLE_SORT_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/make_projected.h> @@ -79,4 +79,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_STABLE_SORT_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_STABLE_SORT_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_starts_with.h b/libcxx/include/__cxx03/__algorithm/ranges_starts_with.h index 0e2424a0d8a03..91117ec29413f 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_starts_with.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_starts_with.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H -#define _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_STARTS_WITH_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_STARTS_WITH_H #include <__cxx03/__algorithm/in_in_result.h> #include <__cxx03/__algorithm/ranges_mismatch.h> @@ -92,4 +92,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_STARTS_WITH_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_STARTS_WITH_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_swap_ranges.h b/libcxx/include/__cxx03/__algorithm/ranges_swap_ranges.h index 610e7c315486b..46a868f3a563f 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_swap_ranges.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_swap_ranges.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H -#define _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_SWAP_RANGES_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_SWAP_RANGES_H #include <__cxx03/__algorithm/in_in_result.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -67,4 +67,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_SWAP_RANGES_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_SWAP_RANGES_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_transform.h b/libcxx/include/__cxx03/__algorithm/ranges_transform.h index 12e4a50154aae..ba6ec5a3ea201 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_transform.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_transform.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H -#define _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_TRANSFORM_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_TRANSFORM_H #include <__cxx03/__algorithm/in_in_out_result.h> #include <__cxx03/__algorithm/in_out_result.h> @@ -174,4 +174,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_TRANSFORM_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_TRANSFORM_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_unique.h b/libcxx/include/__cxx03/__algorithm/ranges_unique.h index 0893127dd9d17..d54b1c5205c28 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_unique.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_unique.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_UNIQUE_H -#define _LIBCPP___ALGORITHM_RANGES_UNIQUE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_UNIQUE_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_UNIQUE_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/make_projected.h> @@ -79,4 +79,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_UNIQUE_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_unique_copy.h b/libcxx/include/__cxx03/__algorithm/ranges_unique_copy.h index c30332a217f7e..6eed79b258998 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_unique_copy.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_unique_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H -#define _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_UNIQUE_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_UNIQUE_COPY_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -117,4 +117,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_RANGES_UNIQUE_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_UNIQUE_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/ranges_upper_bound.h b/libcxx/include/__cxx03/__algorithm/ranges_upper_bound.h index 79b49ab804b3b..004b9ae654f85 100644 --- a/libcxx/include/__cxx03/__algorithm/ranges_upper_bound.h +++ b/libcxx/include/__cxx03/__algorithm/ranges_upper_bound.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H -#define _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_UPPER_BOUND_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_UPPER_BOUND_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/lower_bound.h> @@ -71,4 +71,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___ALGORITHM_RANGES_UPPER_BOUND_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_UPPER_BOUND_H diff --git a/libcxx/include/__cxx03/__algorithm/remove.h b/libcxx/include/__cxx03/__algorithm/remove.h index 7849527585b17..208351e22ac90 100644 --- a/libcxx/include/__cxx03/__algorithm/remove.h +++ b/libcxx/include/__cxx03/__algorithm/remove.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_REMOVE_H -#define _LIBCPP___ALGORITHM_REMOVE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_REMOVE_H +#define _LIBCPP___CXX03___ALGORITHM_REMOVE_H #include <__cxx03/__algorithm/find.h> #include <__cxx03/__algorithm/find_if.h> @@ -43,4 +43,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_REMOVE_H +#endif // _LIBCPP___CXX03___ALGORITHM_REMOVE_H diff --git a/libcxx/include/__cxx03/__algorithm/remove_copy.h b/libcxx/include/__cxx03/__algorithm/remove_copy.h index e79c798127161..1bed25224281b 100644 --- a/libcxx/include/__cxx03/__algorithm/remove_copy.h +++ b/libcxx/include/__cxx03/__algorithm/remove_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_REMOVE_COPY_H -#define _LIBCPP___ALGORITHM_REMOVE_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_REMOVE_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_REMOVE_COPY_H #include <__cxx03/__config> @@ -31,4 +31,4 @@ remove_copy(_InputIterator __first, _InputIterator __last, _OutputIterator __res _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_REMOVE_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_REMOVE_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/remove_copy_if.h b/libcxx/include/__cxx03/__algorithm/remove_copy_if.h index 7132e3c0bdb1a..3ec019dfd5912 100644 --- a/libcxx/include/__cxx03/__algorithm/remove_copy_if.h +++ b/libcxx/include/__cxx03/__algorithm/remove_copy_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H -#define _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_REMOVE_COPY_IF_H +#define _LIBCPP___CXX03___ALGORITHM_REMOVE_COPY_IF_H #include <__cxx03/__config> @@ -31,4 +31,4 @@ remove_copy_if(_InputIterator __first, _InputIterator __last, _OutputIterator __ _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_REMOVE_COPY_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_REMOVE_COPY_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/remove_if.h b/libcxx/include/__cxx03/__algorithm/remove_if.h index e6dc3d15fbc9c..c64e0aa4477e5 100644 --- a/libcxx/include/__cxx03/__algorithm/remove_if.h +++ b/libcxx/include/__cxx03/__algorithm/remove_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_REMOVE_IF_H -#define _LIBCPP___ALGORITHM_REMOVE_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_REMOVE_IF_H +#define _LIBCPP___CXX03___ALGORITHM_REMOVE_IF_H #include <__cxx03/__algorithm/find_if.h> #include <__cxx03/__config> @@ -42,4 +42,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_REMOVE_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_REMOVE_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/replace.h b/libcxx/include/__cxx03/__algorithm/replace.h index 2b24752f048ef..692cece1708f9 100644 --- a/libcxx/include/__cxx03/__algorithm/replace.h +++ b/libcxx/include/__cxx03/__algorithm/replace.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_REPLACE_H -#define _LIBCPP___ALGORITHM_REPLACE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_REPLACE_H +#define _LIBCPP___CXX03___ALGORITHM_REPLACE_H #include <__cxx03/__config> @@ -27,4 +27,4 @@ replace(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __old_valu _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_REPLACE_H +#endif // _LIBCPP___CXX03___ALGORITHM_REPLACE_H diff --git a/libcxx/include/__cxx03/__algorithm/replace_copy.h b/libcxx/include/__cxx03/__algorithm/replace_copy.h index 6c50dd4e14f57..4f8b375df2fb7 100644 --- a/libcxx/include/__cxx03/__algorithm/replace_copy.h +++ b/libcxx/include/__cxx03/__algorithm/replace_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_REPLACE_COPY_H -#define _LIBCPP___ALGORITHM_REPLACE_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_REPLACE_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_REPLACE_COPY_H #include <__cxx03/__config> @@ -34,4 +34,4 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator repla _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_REPLACE_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_REPLACE_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/replace_copy_if.h b/libcxx/include/__cxx03/__algorithm/replace_copy_if.h index c714d50037339..cfc7b0aa2d34c 100644 --- a/libcxx/include/__cxx03/__algorithm/replace_copy_if.h +++ b/libcxx/include/__cxx03/__algorithm/replace_copy_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H -#define _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_REPLACE_COPY_IF_H +#define _LIBCPP___CXX03___ALGORITHM_REPLACE_COPY_IF_H #include <__cxx03/__config> @@ -34,4 +34,4 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator repla _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_REPLACE_COPY_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_REPLACE_COPY_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/replace_if.h b/libcxx/include/__cxx03/__algorithm/replace_if.h index 8bd9a9c0db979..f46da35714ef3 100644 --- a/libcxx/include/__cxx03/__algorithm/replace_if.h +++ b/libcxx/include/__cxx03/__algorithm/replace_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_REPLACE_IF_H -#define _LIBCPP___ALGORITHM_REPLACE_IF_H +#ifndef _LIBCPP___CXX03___ALGORITHM_REPLACE_IF_H +#define _LIBCPP___CXX03___ALGORITHM_REPLACE_IF_H #include <__cxx03/__config> @@ -27,4 +27,4 @@ replace_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred, _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_REPLACE_IF_H +#endif // _LIBCPP___CXX03___ALGORITHM_REPLACE_IF_H diff --git a/libcxx/include/__cxx03/__algorithm/reverse.h b/libcxx/include/__cxx03/__algorithm/reverse.h index b97ec38490a22..868377c7b26bd 100644 --- a/libcxx/include/__cxx03/__algorithm/reverse.h +++ b/libcxx/include/__cxx03/__algorithm/reverse.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_REVERSE_H -#define _LIBCPP___ALGORITHM_REVERSE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_REVERSE_H +#define _LIBCPP___CXX03___ALGORITHM_REVERSE_H #include <__cxx03/__algorithm/iter_swap.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -59,4 +59,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_REVERSE_H +#endif // _LIBCPP___CXX03___ALGORITHM_REVERSE_H diff --git a/libcxx/include/__cxx03/__algorithm/reverse_copy.h b/libcxx/include/__cxx03/__algorithm/reverse_copy.h index 29070fec8448c..3553102a2d03c 100644 --- a/libcxx/include/__cxx03/__algorithm/reverse_copy.h +++ b/libcxx/include/__cxx03/__algorithm/reverse_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_REVERSE_COPY_H -#define _LIBCPP___ALGORITHM_REVERSE_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_REVERSE_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_REVERSE_COPY_H #include <__cxx03/__config> @@ -27,4 +27,4 @@ reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _Out _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_REVERSE_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_REVERSE_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/rotate.h b/libcxx/include/__cxx03/__algorithm/rotate.h index d6ca9230731ed..e41edf00e7993 100644 --- a/libcxx/include/__cxx03/__algorithm/rotate.h +++ b/libcxx/include/__cxx03/__algorithm/rotate.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_ROTATE_H -#define _LIBCPP___ALGORITHM_ROTATE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_ROTATE_H +#define _LIBCPP___CXX03___ALGORITHM_ROTATE_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/move.h> @@ -195,4 +195,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_ROTATE_H +#endif // _LIBCPP___CXX03___ALGORITHM_ROTATE_H diff --git a/libcxx/include/__cxx03/__algorithm/rotate_copy.h b/libcxx/include/__cxx03/__algorithm/rotate_copy.h index c20d9571e6ffd..6970cdc5a2c56 100644 --- a/libcxx/include/__cxx03/__algorithm/rotate_copy.h +++ b/libcxx/include/__cxx03/__algorithm/rotate_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_ROTATE_COPY_H -#define _LIBCPP___ALGORITHM_ROTATE_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_ROTATE_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_ROTATE_COPY_H #include <__cxx03/__algorithm/copy.h> #include <__cxx03/__config> @@ -26,4 +26,4 @@ rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterato _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_ROTATE_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_ROTATE_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/sample.h b/libcxx/include/__cxx03/__algorithm/sample.h index e6743cf3828c0..55e34c9f24813 100644 --- a/libcxx/include/__cxx03/__algorithm/sample.h +++ b/libcxx/include/__cxx03/__algorithm/sample.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SAMPLE_H -#define _LIBCPP___ALGORITHM_SAMPLE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SAMPLE_H +#define _LIBCPP___CXX03___ALGORITHM_SAMPLE_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/min.h> @@ -120,4 +120,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SAMPLE_H +#endif // _LIBCPP___CXX03___ALGORITHM_SAMPLE_H diff --git a/libcxx/include/__cxx03/__algorithm/search.h b/libcxx/include/__cxx03/__algorithm/search.h index eb862f4ad7ca9..7ca6bdbc2beb5 100644 --- a/libcxx/include/__cxx03/__algorithm/search.h +++ b/libcxx/include/__cxx03/__algorithm/search.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SEARCH_H -#define _LIBCPP___ALGORITHM_SEARCH_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SEARCH_H +#define _LIBCPP___CXX03___ALGORITHM_SEARCH_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -189,4 +189,4 @@ search(_ForwardIterator __f, _ForwardIterator __l, const _Searcher& __s) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_SEARCH_H +#endif // _LIBCPP___CXX03___ALGORITHM_SEARCH_H diff --git a/libcxx/include/__cxx03/__algorithm/search_n.h b/libcxx/include/__cxx03/__algorithm/search_n.h index d6458b8ca90d8..cf63de27666b2 100644 --- a/libcxx/include/__cxx03/__algorithm/search_n.h +++ b/libcxx/include/__cxx03/__algorithm/search_n.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SEARCH_N_H -#define _LIBCPP___ALGORITHM_SEARCH_N_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SEARCH_N_H +#define _LIBCPP___CXX03___ALGORITHM_SEARCH_N_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -152,4 +152,4 @@ search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_SEARCH_N_H +#endif // _LIBCPP___CXX03___ALGORITHM_SEARCH_N_H diff --git a/libcxx/include/__cxx03/__algorithm/set_difference.h b/libcxx/include/__cxx03/__algorithm/set_difference.h index 13d6f0249e436..1bdddd3955980 100644 --- a/libcxx/include/__cxx03/__algorithm/set_difference.h +++ b/libcxx/include/__cxx03/__algorithm/set_difference.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SET_DIFFERENCE_H -#define _LIBCPP___ALGORITHM_SET_DIFFERENCE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SET_DIFFERENCE_H +#define _LIBCPP___CXX03___ALGORITHM_SET_DIFFERENCE_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -76,4 +76,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SET_DIFFERENCE_H +#endif // _LIBCPP___CXX03___ALGORITHM_SET_DIFFERENCE_H diff --git a/libcxx/include/__cxx03/__algorithm/set_intersection.h b/libcxx/include/__cxx03/__algorithm/set_intersection.h index f1193ec349cfd..8164ced338d20 100644 --- a/libcxx/include/__cxx03/__algorithm/set_intersection.h +++ b/libcxx/include/__cxx03/__algorithm/set_intersection.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SET_INTERSECTION_H -#define _LIBCPP___ALGORITHM_SET_INTERSECTION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SET_INTERSECTION_H +#define _LIBCPP___CXX03___ALGORITHM_SET_INTERSECTION_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -214,4 +214,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SET_INTERSECTION_H +#endif // _LIBCPP___CXX03___ALGORITHM_SET_INTERSECTION_H diff --git a/libcxx/include/__cxx03/__algorithm/set_symmetric_difference.h b/libcxx/include/__cxx03/__algorithm/set_symmetric_difference.h index 71aca2b8ed03b..64fdf4543be9c 100644 --- a/libcxx/include/__cxx03/__algorithm/set_symmetric_difference.h +++ b/libcxx/include/__cxx03/__algorithm/set_symmetric_difference.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H -#define _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H +#define _LIBCPP___CXX03___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -106,4 +106,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H +#endif // _LIBCPP___CXX03___ALGORITHM_SET_SYMMETRIC_DIFFERENCE_H diff --git a/libcxx/include/__cxx03/__algorithm/set_union.h b/libcxx/include/__cxx03/__algorithm/set_union.h index f60221cce3cd8..a5c6d5eabd394 100644 --- a/libcxx/include/__cxx03/__algorithm/set_union.h +++ b/libcxx/include/__cxx03/__algorithm/set_union.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SET_UNION_H -#define _LIBCPP___ALGORITHM_SET_UNION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SET_UNION_H +#define _LIBCPP___CXX03___ALGORITHM_SET_UNION_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -102,4 +102,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SET_UNION_H +#endif // _LIBCPP___CXX03___ALGORITHM_SET_UNION_H diff --git a/libcxx/include/__cxx03/__algorithm/shift_left.h b/libcxx/include/__cxx03/__algorithm/shift_left.h index b59a069826710..886f353f2814c 100644 --- a/libcxx/include/__cxx03/__algorithm/shift_left.h +++ b/libcxx/include/__cxx03/__algorithm/shift_left.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SHIFT_LEFT_H -#define _LIBCPP___ALGORITHM_SHIFT_LEFT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SHIFT_LEFT_H +#define _LIBCPP___CXX03___ALGORITHM_SHIFT_LEFT_H #include <__cxx03/__algorithm/move.h> #include <__cxx03/__config> @@ -56,4 +56,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SHIFT_LEFT_H +#endif // _LIBCPP___CXX03___ALGORITHM_SHIFT_LEFT_H diff --git a/libcxx/include/__cxx03/__algorithm/shift_right.h b/libcxx/include/__cxx03/__algorithm/shift_right.h index 51d8ea613245d..4bff76af2fd99 100644 --- a/libcxx/include/__cxx03/__algorithm/shift_right.h +++ b/libcxx/include/__cxx03/__algorithm/shift_right.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SHIFT_RIGHT_H -#define _LIBCPP___ALGORITHM_SHIFT_RIGHT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SHIFT_RIGHT_H +#define _LIBCPP___CXX03___ALGORITHM_SHIFT_RIGHT_H #include <__cxx03/__algorithm/move.h> #include <__cxx03/__algorithm/move_backward.h> @@ -102,4 +102,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SHIFT_RIGHT_H +#endif // _LIBCPP___CXX03___ALGORITHM_SHIFT_RIGHT_H diff --git a/libcxx/include/__cxx03/__algorithm/shuffle.h b/libcxx/include/__cxx03/__algorithm/shuffle.h index 30b372ffe767a..abb96bce40236 100644 --- a/libcxx/include/__cxx03/__algorithm/shuffle.h +++ b/libcxx/include/__cxx03/__algorithm/shuffle.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SHUFFLE_H -#define _LIBCPP___ALGORITHM_SHUFFLE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SHUFFLE_H +#define _LIBCPP___CXX03___ALGORITHM_SHUFFLE_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__config> @@ -164,4 +164,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SHUFFLE_H +#endif // _LIBCPP___CXX03___ALGORITHM_SHUFFLE_H diff --git a/libcxx/include/__cxx03/__algorithm/sift_down.h b/libcxx/include/__cxx03/__algorithm/sift_down.h index 85f0aa92c568d..774a6d2450d57 100644 --- a/libcxx/include/__cxx03/__algorithm/sift_down.h +++ b/libcxx/include/__cxx03/__algorithm/sift_down.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SIFT_DOWN_H -#define _LIBCPP___ALGORITHM_SIFT_DOWN_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SIFT_DOWN_H +#define _LIBCPP___CXX03___ALGORITHM_SIFT_DOWN_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__assert> @@ -115,4 +115,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SIFT_DOWN_H +#endif // _LIBCPP___CXX03___ALGORITHM_SIFT_DOWN_H diff --git a/libcxx/include/__cxx03/__algorithm/simd_utils.h b/libcxx/include/__cxx03/__algorithm/simd_utils.h index 4769a8176a885..db2e20fb65ece 100644 --- a/libcxx/include/__cxx03/__algorithm/simd_utils.h +++ b/libcxx/include/__cxx03/__algorithm/simd_utils.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SIMD_UTILS_H -#define _LIBCPP___ALGORITHM_SIMD_UTILS_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SIMD_UTILS_H +#define _LIBCPP___CXX03___ALGORITHM_SIMD_UTILS_H #include <__cxx03/__algorithm/min.h> #include <__cxx03/__bit/bit_cast.h> @@ -161,4 +161,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SIMD_UTILS_H +#endif // _LIBCPP___CXX03___ALGORITHM_SIMD_UTILS_H diff --git a/libcxx/include/__cxx03/__algorithm/sort.h b/libcxx/include/__cxx03/__algorithm/sort.h index d14ec87b4aea8..009ebf717bbd8 100644 --- a/libcxx/include/__cxx03/__algorithm/sort.h +++ b/libcxx/include/__cxx03/__algorithm/sort.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SORT_H -#define _LIBCPP___ALGORITHM_SORT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SORT_H +#define _LIBCPP___CXX03___ALGORITHM_SORT_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -1013,4 +1013,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SORT_H +#endif // _LIBCPP___CXX03___ALGORITHM_SORT_H diff --git a/libcxx/include/__cxx03/__algorithm/sort_heap.h b/libcxx/include/__cxx03/__algorithm/sort_heap.h index c2d218b8f5e0d..b5a341103980e 100644 --- a/libcxx/include/__cxx03/__algorithm/sort_heap.h +++ b/libcxx/include/__cxx03/__algorithm/sort_heap.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SORT_HEAP_H -#define _LIBCPP___ALGORITHM_SORT_HEAP_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SORT_HEAP_H +#define _LIBCPP___CXX03___ALGORITHM_SORT_HEAP_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -60,4 +60,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SORT_HEAP_H +#endif // _LIBCPP___CXX03___ALGORITHM_SORT_HEAP_H diff --git a/libcxx/include/__cxx03/__algorithm/stable_partition.h b/libcxx/include/__cxx03/__algorithm/stable_partition.h index cea18b30fbb37..c8044987e247a 100644 --- a/libcxx/include/__cxx03/__algorithm/stable_partition.h +++ b/libcxx/include/__cxx03/__algorithm/stable_partition.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_STABLE_PARTITION_H -#define _LIBCPP___ALGORITHM_STABLE_PARTITION_H +#ifndef _LIBCPP___CXX03___ALGORITHM_STABLE_PARTITION_H +#define _LIBCPP___CXX03___ALGORITHM_STABLE_PARTITION_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__algorithm/rotate.h> @@ -304,4 +304,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_STABLE_PARTITION_H +#endif // _LIBCPP___CXX03___ALGORITHM_STABLE_PARTITION_H diff --git a/libcxx/include/__cxx03/__algorithm/stable_sort.h b/libcxx/include/__cxx03/__algorithm/stable_sort.h index 6a3cef7ec1b66..e1f89f6341b9f 100644 --- a/libcxx/include/__cxx03/__algorithm/stable_sort.h +++ b/libcxx/include/__cxx03/__algorithm/stable_sort.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_STABLE_SORT_H -#define _LIBCPP___ALGORITHM_STABLE_SORT_H +#ifndef _LIBCPP___CXX03___ALGORITHM_STABLE_SORT_H +#define _LIBCPP___CXX03___ALGORITHM_STABLE_SORT_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/comp_ref_type.h> @@ -270,4 +270,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_STABLE_SORT_H +#endif // _LIBCPP___CXX03___ALGORITHM_STABLE_SORT_H diff --git a/libcxx/include/__cxx03/__algorithm/swap_ranges.h b/libcxx/include/__cxx03/__algorithm/swap_ranges.h index 12bc8056e3577..9a19ffe602b33 100644 --- a/libcxx/include/__cxx03/__algorithm/swap_ranges.h +++ b/libcxx/include/__cxx03/__algorithm/swap_ranges.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_SWAP_RANGES_H -#define _LIBCPP___ALGORITHM_SWAP_RANGES_H +#ifndef _LIBCPP___CXX03___ALGORITHM_SWAP_RANGES_H +#define _LIBCPP___CXX03___ALGORITHM_SWAP_RANGES_H #include <__cxx03/__algorithm/iterator_operations.h> #include <__cxx03/__config> @@ -59,4 +59,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_SWAP_RANGES_H +#endif // _LIBCPP___CXX03___ALGORITHM_SWAP_RANGES_H diff --git a/libcxx/include/__cxx03/__algorithm/three_way_comp_ref_type.h b/libcxx/include/__cxx03/__algorithm/three_way_comp_ref_type.h index be6a4e4d01482..4463bd2115482 100644 --- a/libcxx/include/__cxx03/__algorithm/three_way_comp_ref_type.h +++ b/libcxx/include/__cxx03/__algorithm/three_way_comp_ref_type.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H -#define _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H +#define _LIBCPP___CXX03___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H #include <__cxx03/__assert> #include <__cxx03/__compare/ordering.h> @@ -71,4 +71,4 @@ using __three_way_comp_ref_type = _Comp&; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H +#endif // _LIBCPP___CXX03___ALGORITHM_THREE_WAY_COMP_REF_TYPE_H diff --git a/libcxx/include/__cxx03/__algorithm/transform.h b/libcxx/include/__cxx03/__algorithm/transform.h index 1608932b050b4..4bed1ed4f8d59 100644 --- a/libcxx/include/__cxx03/__algorithm/transform.h +++ b/libcxx/include/__cxx03/__algorithm/transform.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_TRANSFORM_H -#define _LIBCPP___ALGORITHM_TRANSFORM_H +#ifndef _LIBCPP___CXX03___ALGORITHM_TRANSFORM_H +#define _LIBCPP___CXX03___ALGORITHM_TRANSFORM_H #include <__cxx03/__config> @@ -39,4 +39,4 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator trans _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ALGORITHM_TRANSFORM_H +#endif // _LIBCPP___CXX03___ALGORITHM_TRANSFORM_H diff --git a/libcxx/include/__cxx03/__algorithm/uniform_random_bit_generator_adaptor.h b/libcxx/include/__cxx03/__algorithm/uniform_random_bit_generator_adaptor.h index 25a9e35fd7aa7..8d3858226b992 100644 --- a/libcxx/include/__cxx03/__algorithm/uniform_random_bit_generator_adaptor.h +++ b/libcxx/include/__cxx03/__algorithm/uniform_random_bit_generator_adaptor.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H -#define _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H +#ifndef _LIBCPP___CXX03___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H +#define _LIBCPP___CXX03___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H #include <__cxx03/__config> #include <__cxx03/__functional/invoke.h> @@ -55,4 +55,4 @@ _LIBCPP_POP_MACROS #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H +#endif // _LIBCPP___CXX03___ALGORITHM_RANGES_UNIFORM_RANDOM_BIT_GENERATOR_ADAPTOR_H diff --git a/libcxx/include/__cxx03/__algorithm/unique.h b/libcxx/include/__cxx03/__algorithm/unique.h index 8d21c63eb2b7d..b7eb2849e4e37 100644 --- a/libcxx/include/__cxx03/__algorithm/unique.h +++ b/libcxx/include/__cxx03/__algorithm/unique.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_UNIQUE_H -#define _LIBCPP___ALGORITHM_UNIQUE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_UNIQUE_H +#define _LIBCPP___CXX03___ALGORITHM_UNIQUE_H #include <__cxx03/__algorithm/adjacent_find.h> #include <__cxx03/__algorithm/comp.h> @@ -61,4 +61,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_UNIQUE_H +#endif // _LIBCPP___CXX03___ALGORITHM_UNIQUE_H diff --git a/libcxx/include/__cxx03/__algorithm/unique_copy.h b/libcxx/include/__cxx03/__algorithm/unique_copy.h index cfa95a58f7b09..6d3daefaa1ca5 100644 --- a/libcxx/include/__cxx03/__algorithm/unique_copy.h +++ b/libcxx/include/__cxx03/__algorithm/unique_copy.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_UNIQUE_COPY_H -#define _LIBCPP___ALGORITHM_UNIQUE_COPY_H +#ifndef _LIBCPP___CXX03___ALGORITHM_UNIQUE_COPY_H +#define _LIBCPP___CXX03___ALGORITHM_UNIQUE_COPY_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/iterator_operations.h> @@ -124,4 +124,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_UNIQUE_COPY_H +#endif // _LIBCPP___CXX03___ALGORITHM_UNIQUE_COPY_H diff --git a/libcxx/include/__cxx03/__algorithm/unwrap_iter.h b/libcxx/include/__cxx03/__algorithm/unwrap_iter.h index b3259af17dd03..055f56b9db155 100644 --- a/libcxx/include/__cxx03/__algorithm/unwrap_iter.h +++ b/libcxx/include/__cxx03/__algorithm/unwrap_iter.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_UNWRAP_ITER_H -#define _LIBCPP___ALGORITHM_UNWRAP_ITER_H +#ifndef _LIBCPP___CXX03___ALGORITHM_UNWRAP_ITER_H +#define _LIBCPP___CXX03___ALGORITHM_UNWRAP_ITER_H #include <__cxx03/__config> #include <__cxx03/__iterator/iterator_traits.h> @@ -82,4 +82,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_UNWRAP_ITER_H +#endif // _LIBCPP___CXX03___ALGORITHM_UNWRAP_ITER_H diff --git a/libcxx/include/__cxx03/__algorithm/unwrap_range.h b/libcxx/include/__cxx03/__algorithm/unwrap_range.h index 26045ef7075af..0b81f1e805c8a 100644 --- a/libcxx/include/__cxx03/__algorithm/unwrap_range.h +++ b/libcxx/include/__cxx03/__algorithm/unwrap_range.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_UNWRAP_RANGE_H -#define _LIBCPP___ALGORITHM_UNWRAP_RANGE_H +#ifndef _LIBCPP___CXX03___ALGORITHM_UNWRAP_RANGE_H +#define _LIBCPP___CXX03___ALGORITHM_UNWRAP_RANGE_H #include <__cxx03/__algorithm/unwrap_iter.h> #include <__cxx03/__concepts/constructible.h> @@ -96,4 +96,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_UNWRAP_RANGE_H +#endif // _LIBCPP___CXX03___ALGORITHM_UNWRAP_RANGE_H diff --git a/libcxx/include/__cxx03/__algorithm/upper_bound.h b/libcxx/include/__cxx03/__algorithm/upper_bound.h index 069dd6d253e28..3a0f1f560cb77 100644 --- a/libcxx/include/__cxx03/__algorithm/upper_bound.h +++ b/libcxx/include/__cxx03/__algorithm/upper_bound.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ALGORITHM_UPPER_BOUND_H -#define _LIBCPP___ALGORITHM_UPPER_BOUND_H +#ifndef _LIBCPP___CXX03___ALGORITHM_UPPER_BOUND_H +#define _LIBCPP___CXX03___ALGORITHM_UPPER_BOUND_H #include <__cxx03/__algorithm/comp.h> #include <__cxx03/__algorithm/half_positive.h> @@ -65,4 +65,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ALGORITHM_UPPER_BOUND_H +#endif // _LIBCPP___CXX03___ALGORITHM_UPPER_BOUND_H diff --git a/libcxx/include/__cxx03/__assert b/libcxx/include/__cxx03/__assert index 19a322934e41d..f6c4d8e4a5d09 100644 --- a/libcxx/include/__cxx03/__assert +++ b/libcxx/include/__cxx03/__assert @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ASSERT -#define _LIBCPP___ASSERT +#ifndef _LIBCPP___CXX03___ASSERT +#define _LIBCPP___CXX03___ASSERT #include <__assertion_handler> // Note: this include is generated by CMake and is potentially vendor-provided. #include <__cxx03/__config> @@ -115,4 +115,4 @@ #endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST // clang-format on -#endif // _LIBCPP___ASSERT +#endif // _LIBCPP___CXX03___ASSERT diff --git a/libcxx/include/__cxx03/__atomic/aliases.h b/libcxx/include/__cxx03/__atomic/aliases.h index b5a7685eb4fa8..918ffc35ccf63 100644 --- a/libcxx/include/__cxx03/__atomic/aliases.h +++ b/libcxx/include/__cxx03/__atomic/aliases.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_ALIASES_H -#define _LIBCPP___ATOMIC_ALIASES_H +#ifndef _LIBCPP___CXX03___ATOMIC_ALIASES_H +#define _LIBCPP___CXX03___ATOMIC_ALIASES_H #include <__cxx03/__atomic/atomic.h> #include <__cxx03/__atomic/atomic_lock_free.h> @@ -107,4 +107,4 @@ using atomic_unsigned_lock_free = atomic #include <__cxx03/__atomic/check_memory_order.h> @@ -619,4 +619,4 @@ atomic_fetch_xor_explicit(atomic<_Tp>* __o, typename atomic<_Tp>::value_type __o _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ATOMIC_ATOMIC_H +#endif // _LIBCPP___CXX03___ATOMIC_ATOMIC_H diff --git a/libcxx/include/__cxx03/__atomic/atomic_base.h b/libcxx/include/__cxx03/__atomic/atomic_base.h index ae6aaf4f8284f..e4d4929b8912e 100644 --- a/libcxx/include/__cxx03/__atomic/atomic_base.h +++ b/libcxx/include/__cxx03/__atomic/atomic_base.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_ATOMIC_BASE_H -#define _LIBCPP___ATOMIC_ATOMIC_BASE_H +#ifndef _LIBCPP___CXX03___ATOMIC_ATOMIC_BASE_H +#define _LIBCPP___CXX03___ATOMIC_ATOMIC_BASE_H #include <__cxx03/__atomic/atomic_sync.h> #include <__cxx03/__atomic/check_memory_order.h> @@ -218,4 +218,4 @@ struct __atomic_waitable_traits<__atomic_base<_Tp, _IsIntegral> > { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ATOMIC_ATOMIC_BASE_H +#endif // _LIBCPP___CXX03___ATOMIC_ATOMIC_BASE_H diff --git a/libcxx/include/__cxx03/__atomic/atomic_flag.h b/libcxx/include/__cxx03/__atomic/atomic_flag.h index 6a8471e1f1ec8..c119e9bc498e6 100644 --- a/libcxx/include/__cxx03/__atomic/atomic_flag.h +++ b/libcxx/include/__cxx03/__atomic/atomic_flag.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_ATOMIC_FLAG_H -#define _LIBCPP___ATOMIC_ATOMIC_FLAG_H +#ifndef _LIBCPP___CXX03___ATOMIC_ATOMIC_FLAG_H +#define _LIBCPP___CXX03___ATOMIC_ATOMIC_FLAG_H #include <__cxx03/__atomic/atomic_sync.h> #include <__cxx03/__atomic/contention_t.h> @@ -186,4 +186,4 @@ atomic_flag_notify_all(atomic_flag* __o) _NOEXCEPT { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ATOMIC_ATOMIC_FLAG_H +#endif // _LIBCPP___CXX03___ATOMIC_ATOMIC_FLAG_H diff --git a/libcxx/include/__cxx03/__atomic/atomic_init.h b/libcxx/include/__cxx03/__atomic/atomic_init.h index 666afb93268d6..edabfe1a12bb4 100644 --- a/libcxx/include/__cxx03/__atomic/atomic_init.h +++ b/libcxx/include/__cxx03/__atomic/atomic_init.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_ATOMIC_INIT_H -#define _LIBCPP___ATOMIC_ATOMIC_INIT_H +#ifndef _LIBCPP___CXX03___ATOMIC_ATOMIC_INIT_H +#define _LIBCPP___CXX03___ATOMIC_ATOMIC_INIT_H #include <__cxx03/__config> @@ -22,4 +22,4 @@ # pragma clang deprecated(ATOMIC_VAR_INIT) #endif -#endif // _LIBCPP___ATOMIC_ATOMIC_INIT_H +#endif // _LIBCPP___CXX03___ATOMIC_ATOMIC_INIT_H diff --git a/libcxx/include/__cxx03/__atomic/atomic_lock_free.h b/libcxx/include/__cxx03/__atomic/atomic_lock_free.h index 17dfcfd46106e..297d148babc83 100644 --- a/libcxx/include/__cxx03/__atomic/atomic_lock_free.h +++ b/libcxx/include/__cxx03/__atomic/atomic_lock_free.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H -#define _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H +#ifndef _LIBCPP___CXX03___ATOMIC_ATOMIC_LOCK_FREE_H +#define _LIBCPP___CXX03___ATOMIC_ATOMIC_LOCK_FREE_H #include <__cxx03/__config> @@ -45,4 +45,4 @@ # define ATOMIC_POINTER_LOCK_FREE __GCC_ATOMIC_POINTER_LOCK_FREE #endif -#endif // _LIBCPP___ATOMIC_ATOMIC_LOCK_FREE_H +#endif // _LIBCPP___CXX03___ATOMIC_ATOMIC_LOCK_FREE_H diff --git a/libcxx/include/__cxx03/__atomic/atomic_ref.h b/libcxx/include/__cxx03/__atomic/atomic_ref.h index c19e6a2e5d26d..f30aac3210e27 100644 --- a/libcxx/include/__cxx03/__atomic/atomic_ref.h +++ b/libcxx/include/__cxx03/__atomic/atomic_ref.h @@ -14,8 +14,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_ATOMIC_REF_H -#define _LIBCPP___ATOMIC_ATOMIC_REF_H +#ifndef _LIBCPP___CXX03___ATOMIC_ATOMIC_REF_H +#define _LIBCPP___CXX03___ATOMIC_ATOMIC_REF_H #include <__cxx03/__assert> #include <__cxx03/__atomic/atomic_sync.h> @@ -375,4 +375,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP__ATOMIC_ATOMIC_REF_H +#endif // _LIBCPP___CXX03__ATOMIC_ATOMIC_REF_H diff --git a/libcxx/include/__cxx03/__atomic/atomic_sync.h b/libcxx/include/__cxx03/__atomic/atomic_sync.h index 815c8a1459649..ca029f0384058 100644 --- a/libcxx/include/__cxx03/__atomic/atomic_sync.h +++ b/libcxx/include/__cxx03/__atomic/atomic_sync.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_ATOMIC_SYNC_H -#define _LIBCPP___ATOMIC_ATOMIC_SYNC_H +#ifndef _LIBCPP___CXX03___ATOMIC_ATOMIC_SYNC_H +#define _LIBCPP___CXX03___ATOMIC_ATOMIC_SYNC_H #include <__cxx03/__atomic/contention_t.h> #include <__cxx03/__atomic/cxx_atomic_impl.h> @@ -202,4 +202,4 @@ __atomic_wait(_AtomicWaitable& __a, _Up __val, memory_order __order) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ATOMIC_ATOMIC_SYNC_H +#endif // _LIBCPP___CXX03___ATOMIC_ATOMIC_SYNC_H diff --git a/libcxx/include/__cxx03/__atomic/check_memory_order.h b/libcxx/include/__cxx03/__atomic/check_memory_order.h index 11033ef2c3b49..5661efd4bad27 100644 --- a/libcxx/include/__cxx03/__atomic/check_memory_order.h +++ b/libcxx/include/__cxx03/__atomic/check_memory_order.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H -#define _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H +#ifndef _LIBCPP___CXX03___ATOMIC_CHECK_MEMORY_ORDER_H +#define _LIBCPP___CXX03___ATOMIC_CHECK_MEMORY_ORDER_H #include <__cxx03/__config> @@ -31,4 +31,4 @@ _LIBCPP_DIAGNOSE_WARNING(__m == memory_order_release || __m == memory_order_acq_rel, \ "memory order argument to atomic operation is invalid") -#endif // _LIBCPP___ATOMIC_CHECK_MEMORY_ORDER_H +#endif // _LIBCPP___CXX03___ATOMIC_CHECK_MEMORY_ORDER_H diff --git a/libcxx/include/__cxx03/__atomic/contention_t.h b/libcxx/include/__cxx03/__atomic/contention_t.h index 1f069b01b28e7..a97f0668da2fe 100644 --- a/libcxx/include/__cxx03/__atomic/contention_t.h +++ b/libcxx/include/__cxx03/__atomic/contention_t.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_CONTENTION_T_H -#define _LIBCPP___ATOMIC_CONTENTION_T_H +#ifndef _LIBCPP___CXX03___ATOMIC_CONTENTION_T_H +#define _LIBCPP___CXX03___ATOMIC_CONTENTION_T_H #include <__cxx03/__atomic/cxx_atomic_impl.h> #include <__cxx03/__config> @@ -29,4 +29,4 @@ using __cxx_atomic_contention_t = __cxx_atomic_impl<__cxx_contention_t>; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ATOMIC_CONTENTION_T_H +#endif // _LIBCPP___CXX03___ATOMIC_CONTENTION_T_H diff --git a/libcxx/include/__cxx03/__atomic/cxx_atomic_impl.h b/libcxx/include/__cxx03/__atomic/cxx_atomic_impl.h index f06627f1a8f66..990d283c62d1a 100644 --- a/libcxx/include/__cxx03/__atomic/cxx_atomic_impl.h +++ b/libcxx/include/__cxx03/__atomic/cxx_atomic_impl.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H -#define _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H +#ifndef _LIBCPP___CXX03___ATOMIC_CXX_ATOMIC_IMPL_H +#define _LIBCPP___CXX03___ATOMIC_CXX_ATOMIC_IMPL_H #include <__cxx03/__atomic/memory_order.h> #include <__cxx03/__atomic/to_gcc_order.h> @@ -507,4 +507,4 @@ struct __cxx_atomic_impl : public _Base { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ATOMIC_CXX_ATOMIC_IMPL_H +#endif // _LIBCPP___CXX03___ATOMIC_CXX_ATOMIC_IMPL_H diff --git a/libcxx/include/__cxx03/__atomic/fence.h b/libcxx/include/__cxx03/__atomic/fence.h index 5200cd533bdeb..05eaa83f36406 100644 --- a/libcxx/include/__cxx03/__atomic/fence.h +++ b/libcxx/include/__cxx03/__atomic/fence.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_FENCE_H -#define _LIBCPP___ATOMIC_FENCE_H +#ifndef _LIBCPP___CXX03___ATOMIC_FENCE_H +#define _LIBCPP___CXX03___ATOMIC_FENCE_H #include <__cxx03/__atomic/cxx_atomic_impl.h> #include <__cxx03/__atomic/memory_order.h> @@ -25,4 +25,4 @@ inline _LIBCPP_HIDE_FROM_ABI void atomic_signal_fence(memory_order __m) _NOEXCEP _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ATOMIC_FENCE_H +#endif // _LIBCPP___CXX03___ATOMIC_FENCE_H diff --git a/libcxx/include/__cxx03/__atomic/is_always_lock_free.h b/libcxx/include/__cxx03/__atomic/is_always_lock_free.h index 29c42d9340fdb..45628ae53214b 100644 --- a/libcxx/include/__cxx03/__atomic/is_always_lock_free.h +++ b/libcxx/include/__cxx03/__atomic/is_always_lock_free.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_IS_ALWAYS_LOCK_FREE_H -#define _LIBCPP___ATOMIC_IS_ALWAYS_LOCK_FREE_H +#ifndef _LIBCPP___CXX03___ATOMIC_IS_ALWAYS_LOCK_FREE_H +#define _LIBCPP___CXX03___ATOMIC_IS_ALWAYS_LOCK_FREE_H #include <__cxx03/__config> @@ -25,4 +25,4 @@ struct __libcpp_is_always_lock_free { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ATOMIC_IS_ALWAYS_LOCK_FREE_H +#endif // _LIBCPP___CXX03___ATOMIC_IS_ALWAYS_LOCK_FREE_H diff --git a/libcxx/include/__cxx03/__atomic/kill_dependency.h b/libcxx/include/__cxx03/__atomic/kill_dependency.h index 3deb29f0dbda1..1e0dfc81e3c5c 100644 --- a/libcxx/include/__cxx03/__atomic/kill_dependency.h +++ b/libcxx/include/__cxx03/__atomic/kill_dependency.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_KILL_DEPENDENCY_H -#define _LIBCPP___ATOMIC_KILL_DEPENDENCY_H +#ifndef _LIBCPP___CXX03___ATOMIC_KILL_DEPENDENCY_H +#define _LIBCPP___CXX03___ATOMIC_KILL_DEPENDENCY_H #include <__cxx03/__config> @@ -24,4 +24,4 @@ _LIBCPP_HIDE_FROM_ABI _Tp kill_dependency(_Tp __y) _NOEXCEPT { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ATOMIC_KILL_DEPENDENCY_H +#endif // _LIBCPP___CXX03___ATOMIC_KILL_DEPENDENCY_H diff --git a/libcxx/include/__cxx03/__atomic/memory_order.h b/libcxx/include/__cxx03/__atomic/memory_order.h index 8a7564dc1553e..b8b9dda3d1150 100644 --- a/libcxx/include/__cxx03/__atomic/memory_order.h +++ b/libcxx/include/__cxx03/__atomic/memory_order.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_MEMORY_ORDER_H -#define _LIBCPP___ATOMIC_MEMORY_ORDER_H +#ifndef _LIBCPP___CXX03___ATOMIC_MEMORY_ORDER_H +#define _LIBCPP___CXX03___ATOMIC_MEMORY_ORDER_H #include <__cxx03/__config> #include <__cxx03/__type_traits/is_same.h> @@ -62,4 +62,4 @@ enum memory_order { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ATOMIC_MEMORY_ORDER_H +#endif // _LIBCPP___CXX03___ATOMIC_MEMORY_ORDER_H diff --git a/libcxx/include/__cxx03/__atomic/to_gcc_order.h b/libcxx/include/__cxx03/__atomic/to_gcc_order.h index 41ada88281732..aab3c59602f11 100644 --- a/libcxx/include/__cxx03/__atomic/to_gcc_order.h +++ b/libcxx/include/__cxx03/__atomic/to_gcc_order.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ATOMIC_TO_GCC_ORDER_H -#define _LIBCPP___ATOMIC_TO_GCC_ORDER_H +#ifndef _LIBCPP___CXX03___ATOMIC_TO_GCC_ORDER_H +#define _LIBCPP___CXX03___ATOMIC_TO_GCC_ORDER_H #include <__cxx03/__atomic/memory_order.h> #include <__cxx03/__config> @@ -51,4 +51,4 @@ _LIBCPP_HIDE_FROM_ABI inline _LIBCPP_CONSTEXPR int __to_gcc_failure_order(memory _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ATOMIC_TO_GCC_ORDER_H +#endif // _LIBCPP___CXX03___ATOMIC_TO_GCC_ORDER_H diff --git a/libcxx/include/__cxx03/__bit/bit_cast.h b/libcxx/include/__cxx03/__bit/bit_cast.h index 9f88805e125dc..2613dc4aa332a 100644 --- a/libcxx/include/__cxx03/__bit/bit_cast.h +++ b/libcxx/include/__cxx03/__bit/bit_cast.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___BIT_BIT_CAST_H -#define _LIBCPP___BIT_BIT_CAST_H +#ifndef _LIBCPP___CXX03___BIT_BIT_CAST_H +#define _LIBCPP___CXX03___BIT_BIT_CAST_H #include <__cxx03/__config> #include <__cxx03/__type_traits/is_trivially_copyable.h> @@ -41,4 +41,4 @@ template _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___BIT_BIT_CAST_H +#endif // _LIBCPP___CXX03___BIT_BIT_CAST_H diff --git a/libcxx/include/__cxx03/__bit/bit_ceil.h b/libcxx/include/__cxx03/__bit/bit_ceil.h index b5cb5cc08f422..598344b1d4268 100644 --- a/libcxx/include/__cxx03/__bit/bit_ceil.h +++ b/libcxx/include/__cxx03/__bit/bit_ceil.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___BIT_BIT_CEIL_H -#define _LIBCPP___BIT_BIT_CEIL_H +#ifndef _LIBCPP___CXX03___BIT_BIT_CEIL_H +#define _LIBCPP___CXX03___BIT_BIT_CEIL_H #include <__cxx03/__assert> #include <__cxx03/__bit/countl.h> @@ -51,4 +51,4 @@ template <__libcpp_unsigned_integer _Tp> _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___BIT_BIT_CEIL_H +#endif // _LIBCPP___CXX03___BIT_BIT_CEIL_H diff --git a/libcxx/include/__cxx03/__bit/bit_floor.h b/libcxx/include/__cxx03/__bit/bit_floor.h index 93379be5e2162..b39d73a64e078 100644 --- a/libcxx/include/__cxx03/__bit/bit_floor.h +++ b/libcxx/include/__cxx03/__bit/bit_floor.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___BIT_BIT_FLOOR_H -#define _LIBCPP___BIT_BIT_FLOOR_H +#ifndef _LIBCPP___CXX03___BIT_BIT_FLOOR_H +#define _LIBCPP___CXX03___BIT_BIT_FLOOR_H #include <__cxx03/__bit/bit_log2.h> #include <__cxx03/__concepts/arithmetic.h> @@ -31,4 +31,4 @@ template <__libcpp_unsigned_integer _Tp> _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___BIT_BIT_FLOOR_H +#endif // _LIBCPP___CXX03___BIT_BIT_FLOOR_H diff --git a/libcxx/include/__cxx03/__bit/bit_log2.h b/libcxx/include/__cxx03/__bit/bit_log2.h index 16a7fb1ec3364..1ca80959e6dac 100644 --- a/libcxx/include/__cxx03/__bit/bit_log2.h +++ b/libcxx/include/__cxx03/__bit/bit_log2.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___BIT_BIT_LOG2_H -#define _LIBCPP___BIT_BIT_LOG2_H +#ifndef _LIBCPP___CXX03___BIT_BIT_LOG2_H +#define _LIBCPP___CXX03___BIT_BIT_LOG2_H #include <__cxx03/__bit/countl.h> #include <__cxx03/__concepts/arithmetic.h> @@ -31,4 +31,4 @@ _LIBCPP_HIDE_FROM_ABI constexpr _Tp __bit_log2(_Tp __t) noexcept { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___BIT_BIT_LOG2_H +#endif // _LIBCPP___CXX03___BIT_BIT_LOG2_H diff --git a/libcxx/include/__cxx03/__bit/bit_width.h b/libcxx/include/__cxx03/__bit/bit_width.h index 4832359f75326..e5d9ffd03ca7f 100644 --- a/libcxx/include/__cxx03/__bit/bit_width.h +++ b/libcxx/include/__cxx03/__bit/bit_width.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___BIT_BIT_WIDTH_H -#define _LIBCPP___BIT_BIT_WIDTH_H +#ifndef _LIBCPP___CXX03___BIT_BIT_WIDTH_H +#define _LIBCPP___CXX03___BIT_BIT_WIDTH_H #include <__cxx03/__bit/bit_log2.h> #include <__cxx03/__concepts/arithmetic.h> @@ -30,4 +30,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___BIT_BIT_WIDTH_H +#endif // _LIBCPP___CXX03___BIT_BIT_WIDTH_H diff --git a/libcxx/include/__cxx03/__bit/blsr.h b/libcxx/include/__cxx03/__bit/blsr.h index 5375bdf9208d7..ae1d8b588925d 100644 --- a/libcxx/include/__cxx03/__bit/blsr.h +++ b/libcxx/include/__cxx03/__bit/blsr.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___BIT_BLSR_H -#define _LIBCPP___BIT_BLSR_H +#ifndef _LIBCPP___CXX03___BIT_BLSR_H +#define _LIBCPP___CXX03___BIT_BLSR_H #include <__cxx03/__config> @@ -31,4 +31,4 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR unsigned long long __libcpp_blsr( _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___BIT_BLSR_H +#endif // _LIBCPP___CXX03___BIT_BLSR_H diff --git a/libcxx/include/__cxx03/__bit/byteswap.h b/libcxx/include/__cxx03/__bit/byteswap.h index 6e65600512284..f40d870ca7fc2 100644 --- a/libcxx/include/__cxx03/__bit/byteswap.h +++ b/libcxx/include/__cxx03/__bit/byteswap.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___BIT_BYTESWAP_H -#define _LIBCPP___BIT_BYTESWAP_H +#ifndef _LIBCPP___CXX03___BIT_BYTESWAP_H +#define _LIBCPP___CXX03___BIT_BYTESWAP_H #include <__cxx03/__concepts/arithmetic.h> #include <__cxx03/__config> @@ -50,4 +50,4 @@ template _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___BIT_BYTESWAP_H +#endif // _LIBCPP___CXX03___BIT_BYTESWAP_H diff --git a/libcxx/include/__cxx03/__bit/countl.h b/libcxx/include/__cxx03/__bit/countl.h index 9a4a269a7da2d..0c8181b53408c 100644 --- a/libcxx/include/__cxx03/__bit/countl.h +++ b/libcxx/include/__cxx03/__bit/countl.h @@ -9,8 +9,8 @@ // TODO: __builtin_clzg is available since Clang 19 and GCC 14. When support for older versions is dropped, we can // refactor this code to exclusively use __builtin_clzg. -#ifndef _LIBCPP___BIT_COUNTL_H -#define _LIBCPP___BIT_COUNTL_H +#ifndef _LIBCPP___CXX03___BIT_COUNTL_H +#define _LIBCPP___CXX03___BIT_COUNTL_H #include <__cxx03/__bit/rotate.h> #include <__cxx03/__concepts/arithmetic.h> @@ -110,4 +110,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___BIT_COUNTL_H +#endif // _LIBCPP___CXX03___BIT_COUNTL_H diff --git a/libcxx/include/__cxx03/__bit/countr.h b/libcxx/include/__cxx03/__bit/countr.h index 34525f591048b..d9306a234cb30 100644 --- a/libcxx/include/__cxx03/__bit/countr.h +++ b/libcxx/include/__cxx03/__bit/countr.h @@ -9,8 +9,8 @@ // TODO: __builtin_ctzg is available since Clang 19 and GCC 14. When support for older versions is dropped, we can // refactor this code to exclusively use __builtin_ctzg. -#ifndef _LIBCPP___BIT_COUNTR_H -#define _LIBCPP___BIT_COUNTR_H +#ifndef _LIBCPP___CXX03___BIT_COUNTR_H +#define _LIBCPP___CXX03___BIT_COUNTR_H #include <__cxx03/__bit/rotate.h> #include <__cxx03/__concepts/arithmetic.h> @@ -81,4 +81,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___BIT_COUNTR_H +#endif // _LIBCPP___CXX03___BIT_COUNTR_H diff --git a/libcxx/include/__cxx03/__bit/endian.h b/libcxx/include/__cxx03/__bit/endian.h index ba0a5ac4c2d08..641f827736b4f 100644 --- a/libcxx/include/__cxx03/__bit/endian.h +++ b/libcxx/include/__cxx03/__bit/endian.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___BIT_ENDIAN_H -#define _LIBCPP___BIT_ENDIAN_H +#ifndef _LIBCPP___CXX03___BIT_ENDIAN_H +#define _LIBCPP___CXX03___BIT_ENDIAN_H #include <__cxx03/__config> @@ -35,4 +35,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___BIT_ENDIAN_H +#endif // _LIBCPP___CXX03___BIT_ENDIAN_H diff --git a/libcxx/include/__cxx03/__bit/has_single_bit.h b/libcxx/include/__cxx03/__bit/has_single_bit.h index 8f69d343a6087..07f3f8523d585 100644 --- a/libcxx/include/__cxx03/__bit/has_single_bit.h +++ b/libcxx/include/__cxx03/__bit/has_single_bit.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___BIT_HAS_SINGLE_BIT_H -#define _LIBCPP___BIT_HAS_SINGLE_BIT_H +#ifndef _LIBCPP___CXX03___BIT_HAS_SINGLE_BIT_H +#define _LIBCPP___CXX03___BIT_HAS_SINGLE_BIT_H #include <__cxx03/__concepts/arithmetic.h> #include <__cxx03/__config> @@ -34,4 +34,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___BIT_HAS_SINGLE_BIT_H +#endif // _LIBCPP___CXX03___BIT_HAS_SINGLE_BIT_H diff --git a/libcxx/include/__cxx03/__bit/invert_if.h b/libcxx/include/__cxx03/__bit/invert_if.h index 0b729bc79c192..b111d702ea755 100644 --- a/libcxx/include/__cxx03/__bit/invert_if.h +++ b/libcxx/include/__cxx03/__bit/invert_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___BIT_INVERT_IF_H -#define _LIBCPP___BIT_INVERT_IF_H +#ifndef _LIBCPP___CXX03___BIT_INVERT_IF_H +#define _LIBCPP___CXX03___BIT_INVERT_IF_H #include <__cxx03/__concepts/arithmetic.h> #include <__cxx03/__config> @@ -27,4 +27,4 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 _Tp __invert_if(_Tp __v) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___BIT_INVERT_IF_H +#endif // _LIBCPP___CXX03___BIT_INVERT_IF_H diff --git a/libcxx/include/__cxx03/__bit/popcount.h b/libcxx/include/__cxx03/__bit/popcount.h index 70a12ea260741..835c07703f233 100644 --- a/libcxx/include/__cxx03/__bit/popcount.h +++ b/libcxx/include/__cxx03/__bit/popcount.h @@ -9,8 +9,8 @@ // TODO: __builtin_popcountg is available since Clang 19 and GCC 14. When support for older versions is dropped, we can // refactor this code to exclusively use __builtin_popcountg. -#ifndef _LIBCPP___BIT_POPCOUNT_H -#define _LIBCPP___BIT_POPCOUNT_H +#ifndef _LIBCPP___CXX03___BIT_POPCOUNT_H +#define _LIBCPP___CXX03___BIT_POPCOUNT_H #include <__cxx03/__bit/rotate.h> #include <__cxx03/__concepts/arithmetic.h> @@ -68,4 +68,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___BIT_POPCOUNT_H +#endif // _LIBCPP___CXX03___BIT_POPCOUNT_H diff --git a/libcxx/include/__cxx03/__bit/rotate.h b/libcxx/include/__cxx03/__bit/rotate.h index 02b4ac66af109..0ce3d2c7629db 100644 --- a/libcxx/include/__cxx03/__bit/rotate.h +++ b/libcxx/include/__cxx03/__bit/rotate.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___BIT_ROTATE_H -#define _LIBCPP___BIT_ROTATE_H +#ifndef _LIBCPP___CXX03___BIT_ROTATE_H +#define _LIBCPP___CXX03___BIT_ROTATE_H #include <__cxx03/__concepts/arithmetic.h> #include <__cxx03/__config> @@ -69,4 +69,4 @@ template <__libcpp_unsigned_integer _Tp> _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___BIT_ROTATE_H +#endif // _LIBCPP___CXX03___BIT_ROTATE_H diff --git a/libcxx/include/__cxx03/__bit_reference b/libcxx/include/__cxx03/__bit_reference index 7339f5bd8c9e1..bf86f9a76e24a 100644 --- a/libcxx/include/__cxx03/__bit_reference +++ b/libcxx/include/__cxx03/__bit_reference @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___BIT_REFERENCE -#define _LIBCPP___BIT_REFERENCE +#ifndef _LIBCPP___CXX03___BIT_REFERENCE +#define _LIBCPP___CXX03___BIT_REFERENCE #include <__cxx03/__algorithm/copy_n.h> #include <__cxx03/__algorithm/fill_n.h> @@ -1021,4 +1021,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___BIT_REFERENCE +#endif // _LIBCPP___CXX03___BIT_REFERENCE diff --git a/libcxx/include/__cxx03/__charconv/chars_format.h b/libcxx/include/__cxx03/__charconv/chars_format.h index c206289c0c258..a886521832eff 100644 --- a/libcxx/include/__cxx03/__charconv/chars_format.h +++ b/libcxx/include/__cxx03/__charconv/chars_format.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHARCONV_CHARS_FORMAT_H -#define _LIBCPP___CHARCONV_CHARS_FORMAT_H +#ifndef _LIBCPP___CXX03___CHARCONV_CHARS_FORMAT_H +#define _LIBCPP___CXX03___CHARCONV_CHARS_FORMAT_H #include <__cxx03/__config> #include <__cxx03/__utility/to_underlying.h> @@ -58,4 +58,4 @@ inline _LIBCPP_HIDE_FROM_ABI constexpr chars_format& operator^=(chars_format& __ _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHARCONV_CHARS_FORMAT_H +#endif // _LIBCPP___CXX03___CHARCONV_CHARS_FORMAT_H diff --git a/libcxx/include/__cxx03/__charconv/from_chars_integral.h b/libcxx/include/__cxx03/__charconv/from_chars_integral.h index a3d6e5537280d..ba3746fcf776e 100644 --- a/libcxx/include/__cxx03/__charconv/from_chars_integral.h +++ b/libcxx/include/__cxx03/__charconv/from_chars_integral.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHARCONV_FROM_CHARS_INTEGRAL_H -#define _LIBCPP___CHARCONV_FROM_CHARS_INTEGRAL_H +#ifndef _LIBCPP___CXX03___CHARCONV_FROM_CHARS_INTEGRAL_H +#define _LIBCPP___CXX03___CHARCONV_FROM_CHARS_INTEGRAL_H #include <__cxx03/__algorithm/copy_n.h> #include <__cxx03/__assert> @@ -237,4 +237,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___CHARCONV_FROM_CHARS_INTEGRAL_H +#endif // _LIBCPP___CXX03___CHARCONV_FROM_CHARS_INTEGRAL_H diff --git a/libcxx/include/__cxx03/__charconv/from_chars_result.h b/libcxx/include/__cxx03/__charconv/from_chars_result.h index 8bba738969e34..03e490fce56a9 100644 --- a/libcxx/include/__cxx03/__charconv/from_chars_result.h +++ b/libcxx/include/__cxx03/__charconv/from_chars_result.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H -#define _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H +#ifndef _LIBCPP___CXX03___CHARCONV_FROM_CHARS_RESULT_H +#define _LIBCPP___CXX03___CHARCONV_FROM_CHARS_RESULT_H #include <__cxx03/__config> #include <__cxx03/__system_error/errc.h> @@ -36,4 +36,4 @@ struct _LIBCPP_EXPORTED_FROM_ABI from_chars_result { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHARCONV_FROM_CHARS_RESULT_H +#endif // _LIBCPP___CXX03___CHARCONV_FROM_CHARS_RESULT_H diff --git a/libcxx/include/__cxx03/__charconv/tables.h b/libcxx/include/__cxx03/__charconv/tables.h index 110352a4be0c7..8c9fd3daf170c 100644 --- a/libcxx/include/__cxx03/__charconv/tables.h +++ b/libcxx/include/__cxx03/__charconv/tables.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHARCONV_TABLES -#define _LIBCPP___CHARCONV_TABLES +#ifndef _LIBCPP___CXX03___CHARCONV_TABLES +#define _LIBCPP___CXX03___CHARCONV_TABLES #include <__cxx03/__config> #include <__cxx03/cstdint> @@ -160,4 +160,4 @@ inline constexpr char __digits_base_10[200] = { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHARCONV_TABLES +#endif // _LIBCPP___CXX03___CHARCONV_TABLES diff --git a/libcxx/include/__cxx03/__charconv/to_chars.h b/libcxx/include/__cxx03/__charconv/to_chars.h index 2db35ace09439..e526ce427c22f 100644 --- a/libcxx/include/__cxx03/__charconv/to_chars.h +++ b/libcxx/include/__cxx03/__charconv/to_chars.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHARCONV_TO_CHARS -#define _LIBCPP___CHARCONV_TO_CHARS +#ifndef _LIBCPP___CXX03___CHARCONV_TO_CHARS +#define _LIBCPP___CXX03___CHARCONV_TO_CHARS #include <__cxx03/__charconv/to_chars_floating_point.h> #include <__cxx03/__charconv/to_chars_integral.h> @@ -22,4 +22,4 @@ _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHARCONV_TO_CHARS +#endif // _LIBCPP___CXX03___CHARCONV_TO_CHARS diff --git a/libcxx/include/__cxx03/__charconv/to_chars_base_10.h b/libcxx/include/__cxx03/__charconv/to_chars_base_10.h index 33baaf63caeef..b13b3e33d8f97 100644 --- a/libcxx/include/__cxx03/__charconv/to_chars_base_10.h +++ b/libcxx/include/__cxx03/__charconv/to_chars_base_10.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H -#define _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H +#ifndef _LIBCPP___CXX03___CHARCONV_TO_CHARS_BASE_10_H +#define _LIBCPP___CXX03___CHARCONV_TO_CHARS_BASE_10_H #include <__cxx03/__algorithm/copy_n.h> #include <__cxx03/__assert> @@ -185,4 +185,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___CHARCONV_TO_CHARS_BASE_10_H +#endif // _LIBCPP___CXX03___CHARCONV_TO_CHARS_BASE_10_H diff --git a/libcxx/include/__cxx03/__charconv/to_chars_floating_point.h b/libcxx/include/__cxx03/__charconv/to_chars_floating_point.h index 305b7e71a6b7e..167ffeae7bedd 100644 --- a/libcxx/include/__cxx03/__charconv/to_chars_floating_point.h +++ b/libcxx/include/__cxx03/__charconv/to_chars_floating_point.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H -#define _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H +#ifndef _LIBCPP___CXX03___CHARCONV_TO_CHARS_FLOATING_POINT_H +#define _LIBCPP___CXX03___CHARCONV_TO_CHARS_FLOATING_POINT_H #include <__cxx03/__charconv/chars_format.h> #include <__cxx03/__charconv/to_chars_result.h> @@ -52,4 +52,4 @@ to_chars(char* __first, char* __last, long double __value, chars_format __fmt, i _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHARCONV_TO_CHARS_FLOATING_POINT_H +#endif // _LIBCPP___CXX03___CHARCONV_TO_CHARS_FLOATING_POINT_H diff --git a/libcxx/include/__cxx03/__charconv/to_chars_integral.h b/libcxx/include/__cxx03/__charconv/to_chars_integral.h index 0b3f319e75125..2579e02229851 100644 --- a/libcxx/include/__cxx03/__charconv/to_chars_integral.h +++ b/libcxx/include/__cxx03/__charconv/to_chars_integral.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H -#define _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H +#ifndef _LIBCPP___CXX03___CHARCONV_TO_CHARS_INTEGRAL_H +#define _LIBCPP___CXX03___CHARCONV_TO_CHARS_INTEGRAL_H #include <__cxx03/__algorithm/copy_n.h> #include <__cxx03/__assert> @@ -324,4 +324,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___CHARCONV_TO_CHARS_INTEGRAL_H +#endif // _LIBCPP___CXX03___CHARCONV_TO_CHARS_INTEGRAL_H diff --git a/libcxx/include/__cxx03/__charconv/to_chars_result.h b/libcxx/include/__cxx03/__charconv/to_chars_result.h index 72fef89dcc5f5..82a60db6f6741 100644 --- a/libcxx/include/__cxx03/__charconv/to_chars_result.h +++ b/libcxx/include/__cxx03/__charconv/to_chars_result.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHARCONV_TO_CHARS_RESULT_H -#define _LIBCPP___CHARCONV_TO_CHARS_RESULT_H +#ifndef _LIBCPP___CXX03___CHARCONV_TO_CHARS_RESULT_H +#define _LIBCPP___CXX03___CHARCONV_TO_CHARS_RESULT_H #include <__cxx03/__config> #include <__cxx03/__system_error/errc.h> @@ -36,4 +36,4 @@ struct _LIBCPP_EXPORTED_FROM_ABI to_chars_result { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHARCONV_TO_CHARS_RESULT_H +#endif // _LIBCPP___CXX03___CHARCONV_TO_CHARS_RESULT_H diff --git a/libcxx/include/__cxx03/__charconv/traits.h b/libcxx/include/__cxx03/__charconv/traits.h index 5eafa6caa39e5..110ff9c07e7d0 100644 --- a/libcxx/include/__cxx03/__charconv/traits.h +++ b/libcxx/include/__cxx03/__charconv/traits.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHARCONV_TRAITS -#define _LIBCPP___CHARCONV_TRAITS +#ifndef _LIBCPP___CXX03___CHARCONV_TRAITS +#define _LIBCPP___CXX03___CHARCONV_TRAITS #include <__cxx03/__assert> #include <__cxx03/__bit/countl.h> @@ -197,4 +197,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___CHARCONV_TRAITS +#endif // _LIBCPP___CXX03___CHARCONV_TRAITS diff --git a/libcxx/include/__cxx03/__chrono/calendar.h b/libcxx/include/__cxx03/__chrono/calendar.h index 5d8e396851ae8..4113ca435cc1e 100644 --- a/libcxx/include/__cxx03/__chrono/calendar.h +++ b/libcxx/include/__cxx03/__chrono/calendar.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_CALENDAR_H -#define _LIBCPP___CHRONO_CALENDAR_H +#ifndef _LIBCPP___CXX03___CHRONO_CALENDAR_H +#define _LIBCPP___CXX03___CHRONO_CALENDAR_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__chrono/time_point.h> @@ -41,4 +41,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___CHRONO_CALENDAR_H +#endif // _LIBCPP___CXX03___CHRONO_CALENDAR_H diff --git a/libcxx/include/__cxx03/__chrono/concepts.h b/libcxx/include/__cxx03/__chrono/concepts.h index 1fb5241055474..55a2c54fc3f5b 100644 --- a/libcxx/include/__cxx03/__chrono/concepts.h +++ b/libcxx/include/__cxx03/__chrono/concepts.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_CONCEPTS_H -#define _LIBCPP___CHRONO_CONCEPTS_H +#ifndef _LIBCPP___CXX03___CHRONO_CONCEPTS_H +#define _LIBCPP___CXX03___CHRONO_CONCEPTS_H #include <__cxx03/__chrono/hh_mm_ss.h> #include <__cxx03/__chrono/time_point.h> @@ -33,4 +33,4 @@ concept __is_time_point = __is_specialization_v<_Tp, chrono::time_point>; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHRONO_CONCEPTS_H +#endif // _LIBCPP___CXX03___CHRONO_CONCEPTS_H diff --git a/libcxx/include/__cxx03/__chrono/convert_to_timespec.h b/libcxx/include/__cxx03/__chrono/convert_to_timespec.h index df0e7714ddd70..24d77c21807eb 100644 --- a/libcxx/include/__cxx03/__chrono/convert_to_timespec.h +++ b/libcxx/include/__cxx03/__chrono/convert_to_timespec.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H -#define _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H +#ifndef _LIBCPP___CXX03___CHRONO_CONVERT_TO_TIMESPEC_H +#define _LIBCPP___CXX03___CHRONO_CONVERT_TO_TIMESPEC_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__config> @@ -48,4 +48,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___CHRONO_CONVERT_TO_TIMESPEC_H +#endif // _LIBCPP___CXX03___CHRONO_CONVERT_TO_TIMESPEC_H diff --git a/libcxx/include/__cxx03/__chrono/convert_to_tm.h b/libcxx/include/__cxx03/__chrono/convert_to_tm.h index ccc7ee7b11973..e02ede48317b7 100644 --- a/libcxx/include/__cxx03/__chrono/convert_to_tm.h +++ b/libcxx/include/__cxx03/__chrono/convert_to_tm.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_CONVERT_TO_TM_H -#define _LIBCPP___CHRONO_CONVERT_TO_TM_H +#ifndef _LIBCPP___CXX03___CHRONO_CONVERT_TO_TM_H +#define _LIBCPP___CXX03___CHRONO_CONVERT_TO_TM_H #include <__cxx03/__chrono/calendar.h> #include <__cxx03/__chrono/concepts.h> @@ -199,4 +199,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___CHRONO_CONVERT_TO_TM_H +#endif // _LIBCPP___CXX03___CHRONO_CONVERT_TO_TM_H diff --git a/libcxx/include/__cxx03/__chrono/day.h b/libcxx/include/__cxx03/__chrono/day.h index 6df2aa4283461..6b989ea3c6c24 100644 --- a/libcxx/include/__cxx03/__chrono/day.h +++ b/libcxx/include/__cxx03/__chrono/day.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_DAY_H -#define _LIBCPP___CHRONO_DAY_H +#ifndef _LIBCPP___CXX03___CHRONO_DAY_H +#define _LIBCPP___CXX03___CHRONO_DAY_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__config> @@ -96,4 +96,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___CHRONO_DAY_H +#endif // _LIBCPP___CXX03___CHRONO_DAY_H diff --git a/libcxx/include/__cxx03/__chrono/duration.h b/libcxx/include/__cxx03/__chrono/duration.h index 5fabe08db1bfc..fd936eda44eef 100644 --- a/libcxx/include/__cxx03/__chrono/duration.h +++ b/libcxx/include/__cxx03/__chrono/duration.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_DURATION_H -#define _LIBCPP___CHRONO_DURATION_H +#ifndef _LIBCPP___CXX03___CHRONO_DURATION_H +#define _LIBCPP___CXX03___CHRONO_DURATION_H #include <__cxx03/__compare/ordering.h> #include <__cxx03/__compare/three_way_comparable.h> @@ -547,4 +547,4 @@ _LIBCPP_POP_MACROS # include <__cxx03/type_traits> #endif -#endif // _LIBCPP___CHRONO_DURATION_H +#endif // _LIBCPP___CXX03___CHRONO_DURATION_H diff --git a/libcxx/include/__cxx03/__chrono/exception.h b/libcxx/include/__cxx03/__chrono/exception.h index 3e1a29c203772..4db9d8c1c4edf 100644 --- a/libcxx/include/__cxx03/__chrono/exception.h +++ b/libcxx/include/__cxx03/__chrono/exception.h @@ -9,8 +9,8 @@ // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html -#ifndef _LIBCPP___CHRONO_EXCEPTION_H -#define _LIBCPP___CHRONO_EXCEPTION_H +#ifndef _LIBCPP___CXX03___CHRONO_EXCEPTION_H +#define _LIBCPP___CXX03___CHRONO_EXCEPTION_H #include <__cxx03/version> // Enable the contents of the header only when libc++ was built with experimental features enabled. @@ -132,4 +132,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) -#endif // _LIBCPP___CHRONO_EXCEPTION_H +#endif // _LIBCPP___CXX03___CHRONO_EXCEPTION_H diff --git a/libcxx/include/__cxx03/__chrono/file_clock.h b/libcxx/include/__cxx03/__chrono/file_clock.h index aef92057bd04a..6e2d32b4ef88a 100644 --- a/libcxx/include/__cxx03/__chrono/file_clock.h +++ b/libcxx/include/__cxx03/__chrono/file_clock.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_FILE_CLOCK_H -#define _LIBCPP___CHRONO_FILE_CLOCK_H +#ifndef _LIBCPP___CXX03___CHRONO_FILE_CLOCK_H +#define _LIBCPP___CXX03___CHRONO_FILE_CLOCK_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__chrono/system_clock.h> @@ -77,4 +77,4 @@ struct _FilesystemClock { _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // !_LIBCPP_CXX03_LANG -#endif // _LIBCPP___CHRONO_FILE_CLOCK_H +#endif // _LIBCPP___CXX03___CHRONO_FILE_CLOCK_H diff --git a/libcxx/include/__cxx03/__chrono/formatter.h b/libcxx/include/__cxx03/__chrono/formatter.h index 54e5dff6b97dc..823f6e34c5361 100644 --- a/libcxx/include/__cxx03/__chrono/formatter.h +++ b/libcxx/include/__cxx03/__chrono/formatter.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_FORMATTER_H -#define _LIBCPP___CHRONO_FORMATTER_H +#ifndef _LIBCPP___CXX03___CHRONO_FORMATTER_H +#define _LIBCPP___CXX03___CHRONO_FORMATTER_H #include <__cxx03/__algorithm/ranges_copy.h> #include <__cxx03/__chrono/calendar.h> @@ -987,4 +987,4 @@ struct formatter, _CharT> : public _ _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHRONO_FORMATTER_H +#endif // _LIBCPP___CXX03___CHRONO_FORMATTER_H diff --git a/libcxx/include/__cxx03/__chrono/hh_mm_ss.h b/libcxx/include/__cxx03/__chrono/hh_mm_ss.h index 100687064ed88..e40cfa3a58b8d 100644 --- a/libcxx/include/__cxx03/__chrono/hh_mm_ss.h +++ b/libcxx/include/__cxx03/__chrono/hh_mm_ss.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_HH_MM_SS_H -#define _LIBCPP___CHRONO_HH_MM_SS_H +#ifndef _LIBCPP___CXX03___CHRONO_HH_MM_SS_H +#define _LIBCPP___CXX03___CHRONO_HH_MM_SS_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__chrono/time_point.h> @@ -109,4 +109,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___CHRONO_HH_MM_SS_H +#endif // _LIBCPP___CXX03___CHRONO_HH_MM_SS_H diff --git a/libcxx/include/__cxx03/__chrono/high_resolution_clock.h b/libcxx/include/__cxx03/__chrono/high_resolution_clock.h index 9c5104338421b..3371d16112f97 100644 --- a/libcxx/include/__cxx03/__chrono/high_resolution_clock.h +++ b/libcxx/include/__cxx03/__chrono/high_resolution_clock.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H -#define _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H +#ifndef _LIBCPP___CXX03___CHRONO_HIGH_RESOLUTION_CLOCK_H +#define _LIBCPP___CXX03___CHRONO_HIGH_RESOLUTION_CLOCK_H #include <__cxx03/__chrono/steady_clock.h> #include <__cxx03/__chrono/system_clock.h> @@ -32,4 +32,4 @@ typedef system_clock high_resolution_clock; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHRONO_HIGH_RESOLUTION_CLOCK_H +#endif // _LIBCPP___CXX03___CHRONO_HIGH_RESOLUTION_CLOCK_H diff --git a/libcxx/include/__cxx03/__chrono/leap_second.h b/libcxx/include/__cxx03/__chrono/leap_second.h index 900eff22aa856..d6678bc58d7b1 100644 --- a/libcxx/include/__cxx03/__chrono/leap_second.h +++ b/libcxx/include/__cxx03/__chrono/leap_second.h @@ -9,8 +9,8 @@ // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html -#ifndef _LIBCPP___CHRONO_LEAP_SECOND_H -#define _LIBCPP___CHRONO_LEAP_SECOND_H +#ifndef _LIBCPP___CXX03___CHRONO_LEAP_SECOND_H +#define _LIBCPP___CXX03___CHRONO_LEAP_SECOND_H #include <__cxx03/version> // Enable the contents of the header only when libc++ was built with experimental features enabled. @@ -123,4 +123,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) -#endif // _LIBCPP___CHRONO_LEAP_SECOND_H +#endif // _LIBCPP___CXX03___CHRONO_LEAP_SECOND_H diff --git a/libcxx/include/__cxx03/__chrono/literals.h b/libcxx/include/__cxx03/__chrono/literals.h index d299fb97da3c9..6d0f596aa4ce5 100644 --- a/libcxx/include/__cxx03/__chrono/literals.h +++ b/libcxx/include/__cxx03/__chrono/literals.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_LITERALS_H -#define _LIBCPP___CHRONO_LITERALS_H +#ifndef _LIBCPP___CXX03___CHRONO_LITERALS_H +#define _LIBCPP___CXX03___CHRONO_LITERALS_H #include <__cxx03/__chrono/day.h> #include <__cxx03/__chrono/year.h> @@ -42,4 +42,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___CHRONO_LITERALS_H +#endif // _LIBCPP___CXX03___CHRONO_LITERALS_H diff --git a/libcxx/include/__cxx03/__chrono/local_info.h b/libcxx/include/__cxx03/__chrono/local_info.h index 8e2194c05aba1..1c475ec93c167 100644 --- a/libcxx/include/__cxx03/__chrono/local_info.h +++ b/libcxx/include/__cxx03/__chrono/local_info.h @@ -9,8 +9,8 @@ // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html -#ifndef _LIBCPP___CHRONO_LOCAL_INFO_H -#define _LIBCPP___CHRONO_LOCAL_INFO_H +#ifndef _LIBCPP___CXX03___CHRONO_LOCAL_INFO_H +#define _LIBCPP___CXX03___CHRONO_LOCAL_INFO_H #include <__cxx03/version> // Enable the contents of the header only when libc++ was built with experimental features enabled. @@ -47,4 +47,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) -#endif // _LIBCPP___CHRONO_LOCAL_INFO_H +#endif // _LIBCPP___CXX03___CHRONO_LOCAL_INFO_H diff --git a/libcxx/include/__cxx03/__chrono/month.h b/libcxx/include/__cxx03/__chrono/month.h index fd66bfea2f60d..9ccc85991af71 100644 --- a/libcxx/include/__cxx03/__chrono/month.h +++ b/libcxx/include/__cxx03/__chrono/month.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_MONTH_H -#define _LIBCPP___CHRONO_MONTH_H +#ifndef _LIBCPP___CXX03___CHRONO_MONTH_H +#define _LIBCPP___CXX03___CHRONO_MONTH_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__config> @@ -112,4 +112,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___CHRONO_MONTH_H +#endif // _LIBCPP___CXX03___CHRONO_MONTH_H diff --git a/libcxx/include/__cxx03/__chrono/month_weekday.h b/libcxx/include/__cxx03/__chrono/month_weekday.h index 6595618d822c0..eedc6e9a784bb 100644 --- a/libcxx/include/__cxx03/__chrono/month_weekday.h +++ b/libcxx/include/__cxx03/__chrono/month_weekday.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_MONTH_WEEKDAY_H -#define _LIBCPP___CHRONO_MONTH_WEEKDAY_H +#ifndef _LIBCPP___CXX03___CHRONO_MONTH_WEEKDAY_H +#define _LIBCPP___CXX03___CHRONO_MONTH_WEEKDAY_H #include <__cxx03/__chrono/month.h> #include <__cxx03/__chrono/weekday.h> @@ -102,4 +102,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___CHRONO_MONTH_WEEKDAY_H +#endif // _LIBCPP___CXX03___CHRONO_MONTH_WEEKDAY_H diff --git a/libcxx/include/__cxx03/__chrono/monthday.h b/libcxx/include/__cxx03/__chrono/monthday.h index fe85e6b8bab32..a64584ee2e5f9 100644 --- a/libcxx/include/__cxx03/__chrono/monthday.h +++ b/libcxx/include/__cxx03/__chrono/monthday.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_MONTHDAY_H -#define _LIBCPP___CHRONO_MONTHDAY_H +#ifndef _LIBCPP___CXX03___CHRONO_MONTHDAY_H +#define _LIBCPP___CXX03___CHRONO_MONTHDAY_H #include <__cxx03/__chrono/calendar.h> #include <__cxx03/__chrono/day.h> @@ -130,4 +130,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___CHRONO_MONTHDAY_H +#endif // _LIBCPP___CXX03___CHRONO_MONTHDAY_H diff --git a/libcxx/include/__cxx03/__chrono/ostream.h b/libcxx/include/__cxx03/__chrono/ostream.h index 6ac6b2831e117..fed43890c39b7 100644 --- a/libcxx/include/__cxx03/__chrono/ostream.h +++ b/libcxx/include/__cxx03/__chrono/ostream.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_OSTREAM_H -#define _LIBCPP___CHRONO_OSTREAM_H +#ifndef _LIBCPP___CXX03___CHRONO_OSTREAM_H +#define _LIBCPP___CXX03___CHRONO_OSTREAM_H #include <__cxx03/__chrono/calendar.h> #include <__cxx03/__chrono/day.h> @@ -319,4 +319,4 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const zoned_time<_Duration, _Ti _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHRONO_OSTREAM_H +#endif // _LIBCPP___CXX03___CHRONO_OSTREAM_H diff --git a/libcxx/include/__cxx03/__chrono/parser_std_format_spec.h b/libcxx/include/__cxx03/__chrono/parser_std_format_spec.h index 3a09a21ac54b3..2bec77d8c74dd 100644 --- a/libcxx/include/__cxx03/__chrono/parser_std_format_spec.h +++ b/libcxx/include/__cxx03/__chrono/parser_std_format_spec.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_PARSER_STD_FORMAT_SPEC_H -#define _LIBCPP___CHRONO_PARSER_STD_FORMAT_SPEC_H +#ifndef _LIBCPP___CXX03___CHRONO_PARSER_STD_FORMAT_SPEC_H +#define _LIBCPP___CXX03___CHRONO_PARSER_STD_FORMAT_SPEC_H #include <__cxx03/__config> #include <__cxx03/__format/concepts.h> @@ -413,4 +413,4 @@ class _LIBCPP_TEMPLATE_VIS __parser_chrono { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHRONO_PARSER_STD_FORMAT_SPEC_H +#endif // _LIBCPP___CXX03___CHRONO_PARSER_STD_FORMAT_SPEC_H diff --git a/libcxx/include/__cxx03/__chrono/statically_widen.h b/libcxx/include/__cxx03/__chrono/statically_widen.h index 101a903bc3f28..183078152f61c 100644 --- a/libcxx/include/__cxx03/__chrono/statically_widen.h +++ b/libcxx/include/__cxx03/__chrono/statically_widen.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_STATICALLY_WIDEN_H -#define _LIBCPP___CHRONO_STATICALLY_WIDEN_H +#ifndef _LIBCPP___CXX03___CHRONO_STATICALLY_WIDEN_H +#define _LIBCPP___CXX03___CHRONO_STATICALLY_WIDEN_H // Implements the STATICALLY-WIDEN exposition-only function. ([time.general]/2) @@ -49,4 +49,4 @@ _LIBCPP_HIDE_FROM_ABI constexpr const _CharT* __statically_widen(const char* __s _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHRONO_STATICALLY_WIDEN_H +#endif // _LIBCPP___CXX03___CHRONO_STATICALLY_WIDEN_H diff --git a/libcxx/include/__cxx03/__chrono/steady_clock.h b/libcxx/include/__cxx03/__chrono/steady_clock.h index ad5b64b8142bc..f8a56954f31ad 100644 --- a/libcxx/include/__cxx03/__chrono/steady_clock.h +++ b/libcxx/include/__cxx03/__chrono/steady_clock.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_STEADY_CLOCK_H -#define _LIBCPP___CHRONO_STEADY_CLOCK_H +#ifndef _LIBCPP___CXX03___CHRONO_STEADY_CLOCK_H +#define _LIBCPP___CXX03___CHRONO_STEADY_CLOCK_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__chrono/time_point.h> @@ -39,4 +39,4 @@ class _LIBCPP_EXPORTED_FROM_ABI steady_clock { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHRONO_STEADY_CLOCK_H +#endif // _LIBCPP___CXX03___CHRONO_STEADY_CLOCK_H diff --git a/libcxx/include/__cxx03/__chrono/sys_info.h b/libcxx/include/__cxx03/__chrono/sys_info.h index ed1c7cabd9b60..45c230de91cc1 100644 --- a/libcxx/include/__cxx03/__chrono/sys_info.h +++ b/libcxx/include/__cxx03/__chrono/sys_info.h @@ -9,8 +9,8 @@ // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html -#ifndef _LIBCPP___CHRONO_SYS_INFO_H -#define _LIBCPP___CHRONO_SYS_INFO_H +#ifndef _LIBCPP___CXX03___CHRONO_SYS_INFO_H +#define _LIBCPP___CXX03___CHRONO_SYS_INFO_H #include <__cxx03/version> // Enable the contents of the header only when libc++ was built with experimental features enabled. @@ -48,4 +48,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) -#endif // _LIBCPP___CHRONO_SYS_INFO_H +#endif // _LIBCPP___CXX03___CHRONO_SYS_INFO_H diff --git a/libcxx/include/__cxx03/__chrono/system_clock.h b/libcxx/include/__cxx03/__chrono/system_clock.h index 61382ebdfbe6d..7ae053f3bb409 100644 --- a/libcxx/include/__cxx03/__chrono/system_clock.h +++ b/libcxx/include/__cxx03/__chrono/system_clock.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_SYSTEM_CLOCK_H -#define _LIBCPP___CHRONO_SYSTEM_CLOCK_H +#ifndef _LIBCPP___CXX03___CHRONO_SYSTEM_CLOCK_H +#define _LIBCPP___CXX03___CHRONO_SYSTEM_CLOCK_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__chrono/time_point.h> @@ -49,4 +49,4 @@ using sys_days = sys_time; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CHRONO_SYSTEM_CLOCK_H +#endif // _LIBCPP___CXX03___CHRONO_SYSTEM_CLOCK_H diff --git a/libcxx/include/__cxx03/__chrono/time_point.h b/libcxx/include/__cxx03/__chrono/time_point.h index a26423efb15b4..8703275a75ea7 100644 --- a/libcxx/include/__cxx03/__chrono/time_point.h +++ b/libcxx/include/__cxx03/__chrono/time_point.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_TIME_POINT_H -#define _LIBCPP___CHRONO_TIME_POINT_H +#ifndef _LIBCPP___CXX03___CHRONO_TIME_POINT_H +#define _LIBCPP___CXX03___CHRONO_TIME_POINT_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__compare/ordering.h> @@ -217,4 +217,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___CHRONO_TIME_POINT_H +#endif // _LIBCPP___CXX03___CHRONO_TIME_POINT_H diff --git a/libcxx/include/__cxx03/__chrono/time_zone.h b/libcxx/include/__cxx03/__chrono/time_zone.h index f14646787cf03..a49e9023c0a6a 100644 --- a/libcxx/include/__cxx03/__chrono/time_zone.h +++ b/libcxx/include/__cxx03/__chrono/time_zone.h @@ -9,8 +9,8 @@ // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html -#ifndef _LIBCPP___CHRONO_TIME_ZONE_H -#define _LIBCPP___CHRONO_TIME_ZONE_H +#ifndef _LIBCPP___CXX03___CHRONO_TIME_ZONE_H +#define _LIBCPP___CXX03___CHRONO_TIME_ZONE_H #include <__cxx03/version> // Enable the contents of the header only when libc++ was built with experimental features enabled. @@ -179,4 +179,4 @@ _LIBCPP_POP_MACROS #endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) -#endif // _LIBCPP___CHRONO_TIME_ZONE_H +#endif // _LIBCPP___CXX03___CHRONO_TIME_ZONE_H diff --git a/libcxx/include/__cxx03/__chrono/time_zone_link.h b/libcxx/include/__cxx03/__chrono/time_zone_link.h index a19226b06d866..f97851bcd9811 100644 --- a/libcxx/include/__cxx03/__chrono/time_zone_link.h +++ b/libcxx/include/__cxx03/__chrono/time_zone_link.h @@ -9,8 +9,8 @@ // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html -#ifndef _LIBCPP___CHRONO_TIME_ZONE_LINK_H -#define _LIBCPP___CHRONO_TIME_ZONE_LINK_H +#ifndef _LIBCPP___CXX03___CHRONO_TIME_ZONE_LINK_H +#define _LIBCPP___CXX03___CHRONO_TIME_ZONE_LINK_H #include <__cxx03/version> // Enable the contents of the header only when libc++ was built with experimental features enabled. @@ -76,4 +76,4 @@ _LIBCPP_POP_MACROS #endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) -#endif // _LIBCPP___CHRONO_TIME_ZONE_LINK_H +#endif // _LIBCPP___CXX03___CHRONO_TIME_ZONE_LINK_H diff --git a/libcxx/include/__cxx03/__chrono/tzdb.h b/libcxx/include/__cxx03/__chrono/tzdb.h index cb218314a8e85..69cd19042c35a 100644 --- a/libcxx/include/__cxx03/__chrono/tzdb.h +++ b/libcxx/include/__cxx03/__chrono/tzdb.h @@ -9,8 +9,8 @@ // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html -#ifndef _LIBCPP___CHRONO_TZDB_H -#define _LIBCPP___CHRONO_TZDB_H +#ifndef _LIBCPP___CXX03___CHRONO_TZDB_H +#define _LIBCPP___CXX03___CHRONO_TZDB_H #include <__cxx03/version> // Enable the contents of the header only when libc++ was built with experimental features enabled. @@ -91,4 +91,4 @@ _LIBCPP_POP_MACROS #endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) -#endif // _LIBCPP___CHRONO_TZDB_H +#endif // _LIBCPP___CXX03___CHRONO_TZDB_H diff --git a/libcxx/include/__cxx03/__chrono/tzdb_list.h b/libcxx/include/__cxx03/__chrono/tzdb_list.h index 96d52da88b108..e3fb2a01161a5 100644 --- a/libcxx/include/__cxx03/__chrono/tzdb_list.h +++ b/libcxx/include/__cxx03/__chrono/tzdb_list.h @@ -9,8 +9,8 @@ // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html -#ifndef _LIBCPP___CHRONO_TZDB_LIST_H -#define _LIBCPP___CHRONO_TZDB_LIST_H +#ifndef _LIBCPP___CXX03___CHRONO_TZDB_LIST_H +#define _LIBCPP___CXX03___CHRONO_TZDB_LIST_H #include <__cxx03/version> // Enable the contents of the header only when libc++ was built with experimental features enabled. @@ -105,4 +105,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) -#endif // _LIBCPP___CHRONO_TZDB_LIST_H +#endif // _LIBCPP___CXX03___CHRONO_TZDB_LIST_H diff --git a/libcxx/include/__cxx03/__chrono/weekday.h b/libcxx/include/__cxx03/__chrono/weekday.h index d7a0cc8496dcd..3c152653118d4 100644 --- a/libcxx/include/__cxx03/__chrono/weekday.h +++ b/libcxx/include/__cxx03/__chrono/weekday.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_WEEKDAY_H -#define _LIBCPP___CHRONO_WEEKDAY_H +#ifndef _LIBCPP___CXX03___CHRONO_WEEKDAY_H +#define _LIBCPP___CXX03___CHRONO_WEEKDAY_H #include <__cxx03/__chrono/calendar.h> #include <__cxx03/__chrono/duration.h> @@ -183,4 +183,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___CHRONO_WEEKDAY_H +#endif // _LIBCPP___CXX03___CHRONO_WEEKDAY_H diff --git a/libcxx/include/__cxx03/__chrono/year.h b/libcxx/include/__cxx03/__chrono/year.h index 2850616a7aa21..3594977e2be99 100644 --- a/libcxx/include/__cxx03/__chrono/year.h +++ b/libcxx/include/__cxx03/__chrono/year.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_YEAR_H -#define _LIBCPP___CHRONO_YEAR_H +#ifndef _LIBCPP___CXX03___CHRONO_YEAR_H +#define _LIBCPP___CXX03___CHRONO_YEAR_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__config> @@ -115,4 +115,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___CHRONO_YEAR_H +#endif // _LIBCPP___CXX03___CHRONO_YEAR_H diff --git a/libcxx/include/__cxx03/__chrono/year_month.h b/libcxx/include/__cxx03/__chrono/year_month.h index 75784df9386d8..07652cfc868c1 100644 --- a/libcxx/include/__cxx03/__chrono/year_month.h +++ b/libcxx/include/__cxx03/__chrono/year_month.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_YEAR_MONTH_H -#define _LIBCPP___CHRONO_YEAR_MONTH_H +#ifndef _LIBCPP___CXX03___CHRONO_YEAR_MONTH_H +#define _LIBCPP___CXX03___CHRONO_YEAR_MONTH_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__chrono/month.h> @@ -120,4 +120,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___CHRONO_YEAR_MONTH_H +#endif // _LIBCPP___CXX03___CHRONO_YEAR_MONTH_H diff --git a/libcxx/include/__cxx03/__chrono/year_month_day.h b/libcxx/include/__cxx03/__chrono/year_month_day.h index dff7423a0ffb3..551da3e3a1ffd 100644 --- a/libcxx/include/__cxx03/__chrono/year_month_day.h +++ b/libcxx/include/__cxx03/__chrono/year_month_day.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_YEAR_MONTH_DAY_H -#define _LIBCPP___CHRONO_YEAR_MONTH_DAY_H +#ifndef _LIBCPP___CXX03___CHRONO_YEAR_MONTH_DAY_H +#define _LIBCPP___CXX03___CHRONO_YEAR_MONTH_DAY_H #include <__cxx03/__chrono/calendar.h> #include <__cxx03/__chrono/day.h> @@ -334,4 +334,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___CHRONO_YEAR_MONTH_DAY_H +#endif // _LIBCPP___CXX03___CHRONO_YEAR_MONTH_DAY_H diff --git a/libcxx/include/__cxx03/__chrono/year_month_weekday.h b/libcxx/include/__cxx03/__chrono/year_month_weekday.h index 3177f21964862..3f6974abeb3cc 100644 --- a/libcxx/include/__cxx03/__chrono/year_month_weekday.h +++ b/libcxx/include/__cxx03/__chrono/year_month_weekday.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H -#define _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H +#ifndef _LIBCPP___CXX03___CHRONO_YEAR_MONTH_WEEKDAY_H +#define _LIBCPP___CXX03___CHRONO_YEAR_MONTH_WEEKDAY_H #include <__cxx03/__chrono/calendar.h> #include <__cxx03/__chrono/day.h> @@ -284,4 +284,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___CHRONO_YEAR_MONTH_WEEKDAY_H +#endif // _LIBCPP___CXX03___CHRONO_YEAR_MONTH_WEEKDAY_H diff --git a/libcxx/include/__cxx03/__chrono/zoned_time.h b/libcxx/include/__cxx03/__chrono/zoned_time.h index f3333a4189cc5..7f83dcfc31a84 100644 --- a/libcxx/include/__cxx03/__chrono/zoned_time.h +++ b/libcxx/include/__cxx03/__chrono/zoned_time.h @@ -9,8 +9,8 @@ // For information see https://libcxx.llvm.org/DesignDocs/TimeZone.html -#ifndef _LIBCPP___CHRONO_ZONED_TIME_H -#define _LIBCPP___CHRONO_ZONED_TIME_H +#ifndef _LIBCPP___CXX03___CHRONO_ZONED_TIME_H +#define _LIBCPP___CXX03___CHRONO_ZONED_TIME_H #include <__cxx03/version> // Enable the contents of the header only when libc++ was built with experimental features enabled. @@ -224,4 +224,4 @@ _LIBCPP_POP_MACROS #endif // !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_TZDB) -#endif // _LIBCPP___CHRONO_ZONED_TIME_H +#endif // _LIBCPP___CXX03___CHRONO_ZONED_TIME_H diff --git a/libcxx/include/__cxx03/__compare/common_comparison_category.h b/libcxx/include/__cxx03/__compare/common_comparison_category.h index 795884d13177f..22375e5fe2dcd 100644 --- a/libcxx/include/__cxx03/__compare/common_comparison_category.h +++ b/libcxx/include/__cxx03/__compare/common_comparison_category.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H -#define _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H +#ifndef _LIBCPP___CXX03___COMPARE_COMMON_COMPARISON_CATEGORY_H +#define _LIBCPP___CXX03___COMPARE_COMMON_COMPARISON_CATEGORY_H #include <__cxx03/__compare/ordering.h> #include <__cxx03/__config> @@ -83,4 +83,4 @@ using common_comparison_category_t = typename common_comparison_category<_Ts...> _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___COMPARE_COMMON_COMPARISON_CATEGORY_H +#endif // _LIBCPP___CXX03___COMPARE_COMMON_COMPARISON_CATEGORY_H diff --git a/libcxx/include/__cxx03/__compare/compare_partial_order_fallback.h b/libcxx/include/__cxx03/__compare/compare_partial_order_fallback.h index dc939d8f9a6b8..faddc2faaa853 100644 --- a/libcxx/include/__cxx03/__compare/compare_partial_order_fallback.h +++ b/libcxx/include/__cxx03/__compare/compare_partial_order_fallback.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK -#define _LIBCPP___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK +#ifndef _LIBCPP___CXX03___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK +#define _LIBCPP___CXX03___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK #include <__cxx03/__compare/ordering.h> #include <__cxx03/__compare/partial_order.h> @@ -73,4 +73,4 @@ inline constexpr auto compare_partial_order_fallback = __compare_partial_order_f _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK +#endif // _LIBCPP___CXX03___COMPARE_COMPARE_PARTIAL_ORDER_FALLBACK diff --git a/libcxx/include/__cxx03/__compare/compare_strong_order_fallback.h b/libcxx/include/__cxx03/__compare/compare_strong_order_fallback.h index 5ea1ce7c64d12..6ba4e49712c07 100644 --- a/libcxx/include/__cxx03/__compare/compare_strong_order_fallback.h +++ b/libcxx/include/__cxx03/__compare/compare_strong_order_fallback.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_COMPARE_STRONG_ORDER_FALLBACK -#define _LIBCPP___COMPARE_COMPARE_STRONG_ORDER_FALLBACK +#ifndef _LIBCPP___CXX03___COMPARE_COMPARE_STRONG_ORDER_FALLBACK +#define _LIBCPP___CXX03___COMPARE_COMPARE_STRONG_ORDER_FALLBACK #include <__cxx03/__compare/ordering.h> #include <__cxx03/__compare/strong_order.h> @@ -70,4 +70,4 @@ inline constexpr auto compare_strong_order_fallback = __compare_strong_order_fal _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___COMPARE_COMPARE_STRONG_ORDER_FALLBACK +#endif // _LIBCPP___CXX03___COMPARE_COMPARE_STRONG_ORDER_FALLBACK diff --git a/libcxx/include/__cxx03/__compare/compare_three_way.h b/libcxx/include/__cxx03/__compare/compare_three_way.h index 258ad43103429..78354b107f213 100644 --- a/libcxx/include/__cxx03/__compare/compare_three_way.h +++ b/libcxx/include/__cxx03/__compare/compare_three_way.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_COMPARE_THREE_WAY_H -#define _LIBCPP___COMPARE_COMPARE_THREE_WAY_H +#ifndef _LIBCPP___CXX03___COMPARE_COMPARE_THREE_WAY_H +#define _LIBCPP___CXX03___COMPARE_COMPARE_THREE_WAY_H #include <__cxx03/__compare/three_way_comparable.h> #include <__cxx03/__config> @@ -37,4 +37,4 @@ struct _LIBCPP_TEMPLATE_VIS compare_three_way { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___COMPARE_COMPARE_THREE_WAY_H +#endif // _LIBCPP___CXX03___COMPARE_COMPARE_THREE_WAY_H diff --git a/libcxx/include/__cxx03/__compare/compare_three_way_result.h b/libcxx/include/__cxx03/__compare/compare_three_way_result.h index 7577b9ee15f90..3b5dccc042e54 100644 --- a/libcxx/include/__cxx03/__compare/compare_three_way_result.h +++ b/libcxx/include/__cxx03/__compare/compare_three_way_result.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_COMPARE_THREE_WAY_RESULT_H -#define _LIBCPP___COMPARE_COMPARE_THREE_WAY_RESULT_H +#ifndef _LIBCPP___CXX03___COMPARE_COMPARE_THREE_WAY_RESULT_H +#define _LIBCPP___CXX03___COMPARE_COMPARE_THREE_WAY_RESULT_H #include <__cxx03/__config> #include <__cxx03/__type_traits/make_const_lvalue_ref.h> @@ -42,4 +42,4 @@ using compare_three_way_result_t = typename compare_three_way_result<_Tp, _Up>:: _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___COMPARE_COMPARE_THREE_WAY_RESULT_H +#endif // _LIBCPP___CXX03___COMPARE_COMPARE_THREE_WAY_RESULT_H diff --git a/libcxx/include/__cxx03/__compare/compare_weak_order_fallback.h b/libcxx/include/__cxx03/__compare/compare_weak_order_fallback.h index e12dc8eb5c9c0..ecfee76dff272 100644 --- a/libcxx/include/__cxx03/__compare/compare_weak_order_fallback.h +++ b/libcxx/include/__cxx03/__compare/compare_weak_order_fallback.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_COMPARE_WEAK_ORDER_FALLBACK -#define _LIBCPP___COMPARE_COMPARE_WEAK_ORDER_FALLBACK +#ifndef _LIBCPP___CXX03___COMPARE_COMPARE_WEAK_ORDER_FALLBACK +#define _LIBCPP___CXX03___COMPARE_COMPARE_WEAK_ORDER_FALLBACK #include <__cxx03/__compare/ordering.h> #include <__cxx03/__compare/weak_order.h> @@ -70,4 +70,4 @@ inline constexpr auto compare_weak_order_fallback = __compare_weak_order_fallbac _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___COMPARE_COMPARE_WEAK_ORDER_FALLBACK +#endif // _LIBCPP___CXX03___COMPARE_COMPARE_WEAK_ORDER_FALLBACK diff --git a/libcxx/include/__cxx03/__compare/is_eq.h b/libcxx/include/__cxx03/__compare/is_eq.h index 09cc7a2c85d4e..52370834dc408 100644 --- a/libcxx/include/__cxx03/__compare/is_eq.h +++ b/libcxx/include/__cxx03/__compare/is_eq.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_IS_EQ_H -#define _LIBCPP___COMPARE_IS_EQ_H +#ifndef _LIBCPP___CXX03___COMPARE_IS_EQ_H +#define _LIBCPP___CXX03___COMPARE_IS_EQ_H #include <__cxx03/__compare/ordering.h> #include <__cxx03/__config> @@ -31,4 +31,4 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr bool is_gteq(partial_ordering __c) noexce _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___COMPARE_IS_EQ_H +#endif // _LIBCPP___CXX03___COMPARE_IS_EQ_H diff --git a/libcxx/include/__cxx03/__compare/ordering.h b/libcxx/include/__cxx03/__compare/ordering.h index 71c199991f330..0a497cba682df 100644 --- a/libcxx/include/__cxx03/__compare/ordering.h +++ b/libcxx/include/__cxx03/__compare/ordering.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_ORDERING_H -#define _LIBCPP___COMPARE_ORDERING_H +#ifndef _LIBCPP___CXX03___COMPARE_ORDERING_H +#define _LIBCPP___CXX03___COMPARE_ORDERING_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -275,4 +275,4 @@ concept __comparison_category = __one_of_v<_Tp, partial_ordering, weak_ordering, _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___COMPARE_ORDERING_H +#endif // _LIBCPP___CXX03___COMPARE_ORDERING_H diff --git a/libcxx/include/__cxx03/__compare/partial_order.h b/libcxx/include/__cxx03/__compare/partial_order.h index df8b842e7bf84..119d6581f1242 100644 --- a/libcxx/include/__cxx03/__compare/partial_order.h +++ b/libcxx/include/__cxx03/__compare/partial_order.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_PARTIAL_ORDER -#define _LIBCPP___COMPARE_PARTIAL_ORDER +#ifndef _LIBCPP___CXX03___COMPARE_PARTIAL_ORDER +#define _LIBCPP___CXX03___COMPARE_PARTIAL_ORDER #include <__cxx03/__compare/compare_three_way.h> #include <__cxx03/__compare/ordering.h> @@ -74,4 +74,4 @@ inline constexpr auto partial_order = __partial_order::__fn{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___COMPARE_PARTIAL_ORDER +#endif // _LIBCPP___CXX03___COMPARE_PARTIAL_ORDER diff --git a/libcxx/include/__cxx03/__compare/strong_order.h b/libcxx/include/__cxx03/__compare/strong_order.h index 7522325912351..ee29de2b9260f 100644 --- a/libcxx/include/__cxx03/__compare/strong_order.h +++ b/libcxx/include/__cxx03/__compare/strong_order.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_STRONG_ORDER -#define _LIBCPP___COMPARE_STRONG_ORDER +#ifndef _LIBCPP___CXX03___COMPARE_STRONG_ORDER +#define _LIBCPP___CXX03___COMPARE_STRONG_ORDER #include <__cxx03/__bit/bit_cast.h> #include <__cxx03/__compare/compare_three_way.h> @@ -140,4 +140,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___COMPARE_STRONG_ORDER +#endif // _LIBCPP___CXX03___COMPARE_STRONG_ORDER diff --git a/libcxx/include/__cxx03/__compare/synth_three_way.h b/libcxx/include/__cxx03/__compare/synth_three_way.h index fbaaf61864299..2625ea80bf1b7 100644 --- a/libcxx/include/__cxx03/__compare/synth_three_way.h +++ b/libcxx/include/__cxx03/__compare/synth_three_way.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_SYNTH_THREE_WAY_H -#define _LIBCPP___COMPARE_SYNTH_THREE_WAY_H +#ifndef _LIBCPP___CXX03___COMPARE_SYNTH_THREE_WAY_H +#define _LIBCPP___CXX03___COMPARE_SYNTH_THREE_WAY_H #include <__cxx03/__compare/ordering.h> #include <__cxx03/__compare/three_way_comparable.h> @@ -49,4 +49,4 @@ using __synth_three_way_result = decltype(std::__synth_three_way(std::declval<_T _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___COMPARE_SYNTH_THREE_WAY_H +#endif // _LIBCPP___CXX03___COMPARE_SYNTH_THREE_WAY_H diff --git a/libcxx/include/__cxx03/__compare/three_way_comparable.h b/libcxx/include/__cxx03/__compare/three_way_comparable.h index 9ad84d2bde498..a3539459ea25c 100644 --- a/libcxx/include/__cxx03/__compare/three_way_comparable.h +++ b/libcxx/include/__cxx03/__compare/three_way_comparable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_THREE_WAY_COMPARABLE_H -#define _LIBCPP___COMPARE_THREE_WAY_COMPARABLE_H +#ifndef _LIBCPP___CXX03___COMPARE_THREE_WAY_COMPARABLE_H +#define _LIBCPP___CXX03___COMPARE_THREE_WAY_COMPARABLE_H #include <__cxx03/__compare/common_comparison_category.h> #include <__cxx03/__compare/ordering.h> @@ -52,4 +52,4 @@ concept three_way_comparable_with = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___COMPARE_THREE_WAY_COMPARABLE_H +#endif // _LIBCPP___CXX03___COMPARE_THREE_WAY_COMPARABLE_H diff --git a/libcxx/include/__cxx03/__compare/weak_order.h b/libcxx/include/__cxx03/__compare/weak_order.h index e4c4797c06db6..32ab1b68e459a 100644 --- a/libcxx/include/__cxx03/__compare/weak_order.h +++ b/libcxx/include/__cxx03/__compare/weak_order.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COMPARE_WEAK_ORDER -#define _LIBCPP___COMPARE_WEAK_ORDER +#ifndef _LIBCPP___CXX03___COMPARE_WEAK_ORDER +#define _LIBCPP___CXX03___COMPARE_WEAK_ORDER #include <__cxx03/__compare/compare_three_way.h> #include <__cxx03/__compare/ordering.h> @@ -102,4 +102,4 @@ inline constexpr auto weak_order = __weak_order::__fn{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___COMPARE_WEAK_ORDER +#endif // _LIBCPP___CXX03___COMPARE_WEAK_ORDER diff --git a/libcxx/include/__cxx03/__concepts/arithmetic.h b/libcxx/include/__cxx03/__concepts/arithmetic.h index a8ef1d1532cac..6c5196bcdf790 100644 --- a/libcxx/include/__cxx03/__concepts/arithmetic.h +++ b/libcxx/include/__cxx03/__concepts/arithmetic.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_ARITHMETIC_H -#define _LIBCPP___CONCEPTS_ARITHMETIC_H +#ifndef _LIBCPP___CXX03___CONCEPTS_ARITHMETIC_H +#define _LIBCPP___CXX03___CONCEPTS_ARITHMETIC_H #include <__cxx03/__config> #include <__cxx03/__type_traits/is_floating_point.h> @@ -53,4 +53,4 @@ concept __libcpp_integer = __libcpp_unsigned_integer<_Tp> || __libcpp_signed_int _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_ARITHMETIC_H +#endif // _LIBCPP___CXX03___CONCEPTS_ARITHMETIC_H diff --git a/libcxx/include/__cxx03/__concepts/assignable.h b/libcxx/include/__cxx03/__concepts/assignable.h index 563deb5e4cd69..8b69770222b0a 100644 --- a/libcxx/include/__cxx03/__concepts/assignable.h +++ b/libcxx/include/__cxx03/__concepts/assignable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_ASSIGNABLE_H -#define _LIBCPP___CONCEPTS_ASSIGNABLE_H +#ifndef _LIBCPP___CXX03___CONCEPTS_ASSIGNABLE_H +#define _LIBCPP___CXX03___CONCEPTS_ASSIGNABLE_H #include <__cxx03/__concepts/common_reference_with.h> #include <__cxx03/__concepts/same_as.h> @@ -38,4 +38,4 @@ concept assignable_from = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_ASSIGNABLE_H +#endif // _LIBCPP___CXX03___CONCEPTS_ASSIGNABLE_H diff --git a/libcxx/include/__cxx03/__concepts/boolean_testable.h b/libcxx/include/__cxx03/__concepts/boolean_testable.h index 1f655c1b19cdf..21e03f76d8bb1 100644 --- a/libcxx/include/__cxx03/__concepts/boolean_testable.h +++ b/libcxx/include/__cxx03/__concepts/boolean_testable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_BOOLEAN_TESTABLE_H -#define _LIBCPP___CONCEPTS_BOOLEAN_TESTABLE_H +#ifndef _LIBCPP___CXX03___CONCEPTS_BOOLEAN_TESTABLE_H +#define _LIBCPP___CXX03___CONCEPTS_BOOLEAN_TESTABLE_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__config> @@ -35,4 +35,4 @@ concept __boolean_testable = __boolean_testable_impl<_Tp> && requires(_Tp&& __t) _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_BOOLEAN_TESTABLE_H +#endif // _LIBCPP___CXX03___CONCEPTS_BOOLEAN_TESTABLE_H diff --git a/libcxx/include/__cxx03/__concepts/class_or_enum.h b/libcxx/include/__cxx03/__concepts/class_or_enum.h index ef9a61cdbebf7..a8604e6d9eb61 100644 --- a/libcxx/include/__cxx03/__concepts/class_or_enum.h +++ b/libcxx/include/__cxx03/__concepts/class_or_enum.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_CLASS_OR_ENUM_H -#define _LIBCPP___CONCEPTS_CLASS_OR_ENUM_H +#ifndef _LIBCPP___CXX03___CONCEPTS_CLASS_OR_ENUM_H +#define _LIBCPP___CXX03___CONCEPTS_CLASS_OR_ENUM_H #include <__cxx03/__config> #include <__cxx03/__type_traits/is_class.h> @@ -32,4 +32,4 @@ concept __class_or_enum = is_class_v<_Tp> || is_union_v<_Tp> || is_enum_v<_Tp>; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_CLASS_OR_ENUM_H +#endif // _LIBCPP___CXX03___CONCEPTS_CLASS_OR_ENUM_H diff --git a/libcxx/include/__cxx03/__concepts/common_reference_with.h b/libcxx/include/__cxx03/__concepts/common_reference_with.h index 8e0b5bafe7862..1ffe9f67be48b 100644 --- a/libcxx/include/__cxx03/__concepts/common_reference_with.h +++ b/libcxx/include/__cxx03/__concepts/common_reference_with.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_COMMON_REFERENCE_WITH_H -#define _LIBCPP___CONCEPTS_COMMON_REFERENCE_WITH_H +#ifndef _LIBCPP___CXX03___CONCEPTS_COMMON_REFERENCE_WITH_H +#define _LIBCPP___CXX03___CONCEPTS_COMMON_REFERENCE_WITH_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__concepts/same_as.h> @@ -33,4 +33,4 @@ concept common_reference_with = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_COMMON_REFERENCE_WITH_H +#endif // _LIBCPP___CXX03___CONCEPTS_COMMON_REFERENCE_WITH_H diff --git a/libcxx/include/__cxx03/__concepts/common_with.h b/libcxx/include/__cxx03/__concepts/common_with.h index 37f4e3c30c2b2..ee100052c0c52 100644 --- a/libcxx/include/__cxx03/__concepts/common_with.h +++ b/libcxx/include/__cxx03/__concepts/common_with.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_COMMON_WITH_H -#define _LIBCPP___CONCEPTS_COMMON_WITH_H +#ifndef _LIBCPP___CXX03___CONCEPTS_COMMON_WITH_H +#define _LIBCPP___CXX03___CONCEPTS_COMMON_WITH_H #include <__cxx03/__concepts/common_reference_with.h> #include <__cxx03/__concepts/same_as.h> @@ -49,4 +49,4 @@ concept common_with = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_COMMON_WITH_H +#endif // _LIBCPP___CXX03___CONCEPTS_COMMON_WITH_H diff --git a/libcxx/include/__cxx03/__concepts/constructible.h b/libcxx/include/__cxx03/__concepts/constructible.h index 356ca47626071..2d04667f7d3e4 100644 --- a/libcxx/include/__cxx03/__concepts/constructible.h +++ b/libcxx/include/__cxx03/__concepts/constructible.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_CONSTRUCTIBLE_H -#define _LIBCPP___CONCEPTS_CONSTRUCTIBLE_H +#ifndef _LIBCPP___CXX03___CONCEPTS_CONSTRUCTIBLE_H +#define _LIBCPP___CXX03___CONCEPTS_CONSTRUCTIBLE_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__concepts/destructible.h> @@ -52,4 +52,4 @@ concept copy_constructible = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_CONSTRUCTIBLE_H +#endif // _LIBCPP___CXX03___CONCEPTS_CONSTRUCTIBLE_H diff --git a/libcxx/include/__cxx03/__concepts/convertible_to.h b/libcxx/include/__cxx03/__concepts/convertible_to.h index 4802621c93ef7..af27b76c9c04a 100644 --- a/libcxx/include/__cxx03/__concepts/convertible_to.h +++ b/libcxx/include/__cxx03/__concepts/convertible_to.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H -#define _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H +#ifndef _LIBCPP___CXX03___CONCEPTS_CONVERTIBLE_TO_H +#define _LIBCPP___CXX03___CONCEPTS_CONVERTIBLE_TO_H #include <__cxx03/__config> #include <__cxx03/__type_traits/is_convertible.h> @@ -30,4 +30,4 @@ concept convertible_to = is_convertible_v<_From, _To> && requires { static_cast< _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_CONVERTIBLE_TO_H +#endif // _LIBCPP___CXX03___CONCEPTS_CONVERTIBLE_TO_H diff --git a/libcxx/include/__cxx03/__concepts/copyable.h b/libcxx/include/__cxx03/__concepts/copyable.h index bcadc7382f50f..8ca2d4f940834 100644 --- a/libcxx/include/__cxx03/__concepts/copyable.h +++ b/libcxx/include/__cxx03/__concepts/copyable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_COPYABLE_H -#define _LIBCPP___CONCEPTS_COPYABLE_H +#ifndef _LIBCPP___CXX03___CONCEPTS_COPYABLE_H +#define _LIBCPP___CXX03___CONCEPTS_COPYABLE_H #include <__cxx03/__concepts/assignable.h> #include <__cxx03/__concepts/constructible.h> @@ -38,4 +38,4 @@ concept copyable = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_COPYABLE_H +#endif // _LIBCPP___CXX03___CONCEPTS_COPYABLE_H diff --git a/libcxx/include/__cxx03/__concepts/derived_from.h b/libcxx/include/__cxx03/__concepts/derived_from.h index 861c84f0cf6ba..8112b6c2b70f9 100644 --- a/libcxx/include/__cxx03/__concepts/derived_from.h +++ b/libcxx/include/__cxx03/__concepts/derived_from.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_DERIVED_FROM_H -#define _LIBCPP___CONCEPTS_DERIVED_FROM_H +#ifndef _LIBCPP___CXX03___CONCEPTS_DERIVED_FROM_H +#define _LIBCPP___CXX03___CONCEPTS_DERIVED_FROM_H #include <__cxx03/__config> #include <__cxx03/__type_traits/is_base_of.h> @@ -30,4 +30,4 @@ concept derived_from = is_base_of_v<_Bp, _Dp> && is_convertible_v #include <__cxx03/__type_traits/is_nothrow_destructible.h> @@ -29,4 +29,4 @@ concept destructible = is_nothrow_destructible_v<_Tp>; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_DESTRUCTIBLE_H +#endif // _LIBCPP___CXX03___CONCEPTS_DESTRUCTIBLE_H diff --git a/libcxx/include/__cxx03/__concepts/different_from.h b/libcxx/include/__cxx03/__concepts/different_from.h index bedf3a0bf0b7f..a5d59d47be1d4 100644 --- a/libcxx/include/__cxx03/__concepts/different_from.h +++ b/libcxx/include/__cxx03/__concepts/different_from.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_DIFFERENT_FROM_H -#define _LIBCPP___CONCEPTS_DIFFERENT_FROM_H +#ifndef _LIBCPP___CXX03___CONCEPTS_DIFFERENT_FROM_H +#define _LIBCPP___CXX03___CONCEPTS_DIFFERENT_FROM_H #include <__cxx03/__concepts/same_as.h> #include <__cxx03/__config> @@ -28,4 +28,4 @@ concept __different_from = !same_as, remove_cvref_t<_Up>>; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_DIFFERENT_FROM_H +#endif // _LIBCPP___CXX03___CONCEPTS_DIFFERENT_FROM_H diff --git a/libcxx/include/__cxx03/__concepts/equality_comparable.h b/libcxx/include/__cxx03/__concepts/equality_comparable.h index a77f8f3de60b2..a3a4504bcb627 100644 --- a/libcxx/include/__cxx03/__concepts/equality_comparable.h +++ b/libcxx/include/__cxx03/__concepts/equality_comparable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_EQUALITY_COMPARABLE_H -#define _LIBCPP___CONCEPTS_EQUALITY_COMPARABLE_H +#ifndef _LIBCPP___CXX03___CONCEPTS_EQUALITY_COMPARABLE_H +#define _LIBCPP___CXX03___CONCEPTS_EQUALITY_COMPARABLE_H #include <__cxx03/__concepts/boolean_testable.h> #include <__cxx03/__concepts/common_reference_with.h> @@ -53,4 +53,4 @@ concept equality_comparable_with = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_EQUALITY_COMPARABLE_H +#endif // _LIBCPP___CXX03___CONCEPTS_EQUALITY_COMPARABLE_H diff --git a/libcxx/include/__cxx03/__concepts/invocable.h b/libcxx/include/__cxx03/__concepts/invocable.h index fbbbf16e32fe9..624d8b0a92465 100644 --- a/libcxx/include/__cxx03/__concepts/invocable.h +++ b/libcxx/include/__cxx03/__concepts/invocable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_INVOCABLE_H -#define _LIBCPP___CONCEPTS_INVOCABLE_H +#ifndef _LIBCPP___CXX03___CONCEPTS_INVOCABLE_H +#define _LIBCPP___CXX03___CONCEPTS_INVOCABLE_H #include <__cxx03/__config> #include <__cxx03/__functional/invoke.h> @@ -37,4 +37,4 @@ concept regular_invocable = invocable<_Fn, _Args...>; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_INVOCABLE_H +#endif // _LIBCPP___CXX03___CONCEPTS_INVOCABLE_H diff --git a/libcxx/include/__cxx03/__concepts/movable.h b/libcxx/include/__cxx03/__concepts/movable.h index 883eda880b6f0..a0c3372e88c96 100644 --- a/libcxx/include/__cxx03/__concepts/movable.h +++ b/libcxx/include/__cxx03/__concepts/movable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_MOVABLE_H -#define _LIBCPP___CONCEPTS_MOVABLE_H +#ifndef _LIBCPP___CXX03___CONCEPTS_MOVABLE_H +#define _LIBCPP___CXX03___CONCEPTS_MOVABLE_H #include <__cxx03/__concepts/assignable.h> #include <__cxx03/__concepts/constructible.h> @@ -32,4 +32,4 @@ concept movable = is_object_v<_Tp> && move_constructible<_Tp> && assignable_from _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_MOVABLE_H +#endif // _LIBCPP___CXX03___CONCEPTS_MOVABLE_H diff --git a/libcxx/include/__cxx03/__concepts/predicate.h b/libcxx/include/__cxx03/__concepts/predicate.h index 15007f3b09926..5268854d50269 100644 --- a/libcxx/include/__cxx03/__concepts/predicate.h +++ b/libcxx/include/__cxx03/__concepts/predicate.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_PREDICATE_H -#define _LIBCPP___CONCEPTS_PREDICATE_H +#ifndef _LIBCPP___CXX03___CONCEPTS_PREDICATE_H +#define _LIBCPP___CXX03___CONCEPTS_PREDICATE_H #include <__cxx03/__concepts/boolean_testable.h> #include <__cxx03/__concepts/invocable.h> @@ -31,4 +31,4 @@ concept predicate = regular_invocable<_Fn, _Args...> && __boolean_testable #include <__cxx03/__concepts/semiregular.h> @@ -30,4 +30,4 @@ concept regular = semiregular<_Tp> && equality_comparable<_Tp>; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_REGULAR_H +#endif // _LIBCPP___CXX03___CONCEPTS_REGULAR_H diff --git a/libcxx/include/__cxx03/__concepts/relation.h b/libcxx/include/__cxx03/__concepts/relation.h index 0d90406012e33..67a612979daab 100644 --- a/libcxx/include/__cxx03/__concepts/relation.h +++ b/libcxx/include/__cxx03/__concepts/relation.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_RELATION_H -#define _LIBCPP___CONCEPTS_RELATION_H +#ifndef _LIBCPP___CXX03___CONCEPTS_RELATION_H +#define _LIBCPP___CXX03___CONCEPTS_RELATION_H #include <__cxx03/__concepts/predicate.h> #include <__cxx03/__config> @@ -40,4 +40,4 @@ concept strict_weak_order = relation<_Rp, _Tp, _Up>; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_RELATION_H +#endif // _LIBCPP___CXX03___CONCEPTS_RELATION_H diff --git a/libcxx/include/__cxx03/__concepts/same_as.h b/libcxx/include/__cxx03/__concepts/same_as.h index 6c81ecfbbfe5b..5318cda953189 100644 --- a/libcxx/include/__cxx03/__concepts/same_as.h +++ b/libcxx/include/__cxx03/__concepts/same_as.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_SAME_AS_H -#define _LIBCPP___CONCEPTS_SAME_AS_H +#ifndef _LIBCPP___CXX03___CONCEPTS_SAME_AS_H +#define _LIBCPP___CXX03___CONCEPTS_SAME_AS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/is_same.h> @@ -32,4 +32,4 @@ concept same_as = __same_as_impl<_Tp, _Up> && __same_as_impl<_Up, _Tp>; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_SAME_AS_H +#endif // _LIBCPP___CXX03___CONCEPTS_SAME_AS_H diff --git a/libcxx/include/__cxx03/__concepts/semiregular.h b/libcxx/include/__cxx03/__concepts/semiregular.h index 2a3eb3d667292..06505080f8d36 100644 --- a/libcxx/include/__cxx03/__concepts/semiregular.h +++ b/libcxx/include/__cxx03/__concepts/semiregular.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_SEMIREGULAR_H -#define _LIBCPP___CONCEPTS_SEMIREGULAR_H +#ifndef _LIBCPP___CXX03___CONCEPTS_SEMIREGULAR_H +#define _LIBCPP___CXX03___CONCEPTS_SEMIREGULAR_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__concepts/copyable.h> @@ -30,4 +30,4 @@ concept semiregular = copyable<_Tp> && default_initializable<_Tp>; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_SEMIREGULAR_H +#endif // _LIBCPP___CXX03___CONCEPTS_SEMIREGULAR_H diff --git a/libcxx/include/__cxx03/__concepts/swappable.h b/libcxx/include/__cxx03/__concepts/swappable.h index 333a42ad0c500..95adb0f1b8dad 100644 --- a/libcxx/include/__cxx03/__concepts/swappable.h +++ b/libcxx/include/__cxx03/__concepts/swappable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_SWAPPABLE_H -#define _LIBCPP___CONCEPTS_SWAPPABLE_H +#ifndef _LIBCPP___CXX03___CONCEPTS_SWAPPABLE_H +#define _LIBCPP___CXX03___CONCEPTS_SWAPPABLE_H #include <__cxx03/__concepts/assignable.h> #include <__cxx03/__concepts/class_or_enum.h> @@ -120,4 +120,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___CONCEPTS_SWAPPABLE_H +#endif // _LIBCPP___CXX03___CONCEPTS_SWAPPABLE_H diff --git a/libcxx/include/__cxx03/__concepts/totally_ordered.h b/libcxx/include/__cxx03/__concepts/totally_ordered.h index f35502b58f125..85ba0e4fdf47d 100644 --- a/libcxx/include/__cxx03/__concepts/totally_ordered.h +++ b/libcxx/include/__cxx03/__concepts/totally_ordered.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONCEPTS_TOTALLY_ORDERED_H -#define _LIBCPP___CONCEPTS_TOTALLY_ORDERED_H +#ifndef _LIBCPP___CXX03___CONCEPTS_TOTALLY_ORDERED_H +#define _LIBCPP___CXX03___CONCEPTS_TOTALLY_ORDERED_H #include <__cxx03/__concepts/boolean_testable.h> #include <__cxx03/__concepts/equality_comparable.h> @@ -56,4 +56,4 @@ concept totally_ordered_with = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___CONCEPTS_TOTALLY_ORDERED_H +#endif // _LIBCPP___CXX03___CONCEPTS_TOTALLY_ORDERED_H diff --git a/libcxx/include/__cxx03/__condition_variable/condition_variable.h b/libcxx/include/__cxx03/__condition_variable/condition_variable.h index d96c6928fa7be..8e41ad89914f9 100644 --- a/libcxx/include/__cxx03/__condition_variable/condition_variable.h +++ b/libcxx/include/__cxx03/__condition_variable/condition_variable.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H -#define _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H +#ifndef _LIBCPP___CXX03___CONDITION_VARIABLE_CONDITION_VARIABLE_H +#define _LIBCPP___CXX03___CONDITION_VARIABLE_CONDITION_VARIABLE_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__chrono/steady_clock.h> @@ -241,4 +241,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___CONDITION_VARIABLE_CONDITION_VARIABLE_H +#endif // _LIBCPP___CXX03___CONDITION_VARIABLE_CONDITION_VARIABLE_H diff --git a/libcxx/include/__cxx03/__config b/libcxx/include/__cxx03/__config index 6f77292387776..935fa4cc404f4 100644 --- a/libcxx/include/__cxx03/__config +++ b/libcxx/include/__cxx03/__config @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONFIG -#define _LIBCPP___CONFIG +#ifndef _LIBCPP___CXX03___CONFIG +#define _LIBCPP___CXX03___CONFIG #include <__config_site> #include <__cxx03/__configuration/abi.h> @@ -1225,4 +1225,4 @@ typedef __char32_t char32_t; #endif // __cplusplus -#endif // _LIBCPP___CONFIG +#endif // _LIBCPP___CXX03___CONFIG diff --git a/libcxx/include/__cxx03/__config_site.in b/libcxx/include/__cxx03/__config_site.in index 67022146c9082..174af4be5c4e5 100644 --- a/libcxx/include/__cxx03/__config_site.in +++ b/libcxx/include/__cxx03/__config_site.in @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONFIG_SITE -#define _LIBCPP___CONFIG_SITE +#ifndef _LIBCPP___CXX03___CONFIG_SITE +#define _LIBCPP___CXX03___CONFIG_SITE #cmakedefine _LIBCPP_ABI_VERSION @_LIBCPP_ABI_VERSION@ #cmakedefine _LIBCPP_ABI_NAMESPACE @_LIBCPP_ABI_NAMESPACE@ @@ -53,4 +53,4 @@ # pragma clang diagnostic pop #endif -#endif // _LIBCPP___CONFIG_SITE +#endif // _LIBCPP___CXX03___CONFIG_SITE diff --git a/libcxx/include/__cxx03/__configuration/abi.h b/libcxx/include/__cxx03/__configuration/abi.h index 0d11528877697..9e7f7313c8834 100644 --- a/libcxx/include/__cxx03/__configuration/abi.h +++ b/libcxx/include/__cxx03/__configuration/abi.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONFIGURATION_ABI_H -#define _LIBCPP___CONFIGURATION_ABI_H +#ifndef _LIBCPP___CXX03___CONFIGURATION_ABI_H +#define _LIBCPP___CXX03___CONFIGURATION_ABI_H #include <__config_site> #include <__cxx03/__configuration/compiler.h> @@ -169,4 +169,4 @@ # endif #endif -#endif // _LIBCPP___CONFIGURATION_ABI_H +#endif // _LIBCPP___CXX03___CONFIGURATION_ABI_H diff --git a/libcxx/include/__cxx03/__configuration/availability.h b/libcxx/include/__cxx03/__configuration/availability.h index e54ba50ae9a02..ad45ce01d0a7e 100644 --- a/libcxx/include/__cxx03/__configuration/availability.h +++ b/libcxx/include/__cxx03/__configuration/availability.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONFIGURATION_AVAILABILITY_H -#define _LIBCPP___CONFIGURATION_AVAILABILITY_H +#ifndef _LIBCPP___CXX03___CONFIGURATION_AVAILABILITY_H +#define _LIBCPP___CXX03___CONFIGURATION_AVAILABILITY_H #include <__cxx03/__configuration/compiler.h> #include <__cxx03/__configuration/language.h> @@ -397,4 +397,4 @@ # define _LIBCPP_AVAILABILITY_INIT_PRIMARY_EXCEPTION #endif -#endif // _LIBCPP___CONFIGURATION_AVAILABILITY_H +#endif // _LIBCPP___CXX03___CONFIGURATION_AVAILABILITY_H diff --git a/libcxx/include/__cxx03/__configuration/compiler.h b/libcxx/include/__cxx03/__configuration/compiler.h index 80ece22bb50bd..2f33fb1f6ef4d 100644 --- a/libcxx/include/__cxx03/__configuration/compiler.h +++ b/libcxx/include/__cxx03/__configuration/compiler.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONFIGURATION_COMPILER_H -#define _LIBCPP___CONFIGURATION_COMPILER_H +#ifndef _LIBCPP___CXX03___CONFIGURATION_COMPILER_H +#define _LIBCPP___CXX03___CONFIGURATION_COMPILER_H #include <__config_site> @@ -48,4 +48,4 @@ #endif -#endif // _LIBCPP___CONFIGURATION_COMPILER_H +#endif // _LIBCPP___CXX03___CONFIGURATION_COMPILER_H diff --git a/libcxx/include/__cxx03/__configuration/language.h b/libcxx/include/__cxx03/__configuration/language.h index fa62a7b6f5c2a..604f2d2cd532a 100644 --- a/libcxx/include/__cxx03/__configuration/language.h +++ b/libcxx/include/__cxx03/__configuration/language.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONFIGURATION_LANGUAGE_H -#define _LIBCPP___CONFIGURATION_LANGUAGE_H +#ifndef _LIBCPP___CXX03___CONFIGURATION_LANGUAGE_H +#define _LIBCPP___CXX03___CONFIGURATION_LANGUAGE_H #include <__config_site> @@ -43,4 +43,4 @@ # define _LIBCPP_HAS_NO_EXCEPTIONS #endif -#endif // _LIBCPP___CONFIGURATION_LANGUAGE_H +#endif // _LIBCPP___CXX03___CONFIGURATION_LANGUAGE_H diff --git a/libcxx/include/__cxx03/__configuration/platform.h b/libcxx/include/__cxx03/__configuration/platform.h index 27f68d04e8a8d..b4718986ad10d 100644 --- a/libcxx/include/__cxx03/__configuration/platform.h +++ b/libcxx/include/__cxx03/__configuration/platform.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___CONFIGURATION_PLATFORM_H -#define _LIBCPP___CONFIGURATION_PLATFORM_H +#ifndef _LIBCPP___CXX03___CONFIGURATION_PLATFORM_H +#define _LIBCPP___CXX03___CONFIGURATION_PLATFORM_H #include <__config_site> @@ -51,4 +51,4 @@ # define _LIBCPP_BIG_ENDIAN #endif // __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ -#endif // _LIBCPP___CONFIGURATION_PLATFORM_H +#endif // _LIBCPP___CXX03___CONFIGURATION_PLATFORM_H diff --git a/libcxx/include/__cxx03/__coroutine/coroutine_handle.h b/libcxx/include/__cxx03/__coroutine/coroutine_handle.h index 183d113e2e69b..f96c56bae168b 100644 --- a/libcxx/include/__cxx03/__coroutine/coroutine_handle.h +++ b/libcxx/include/__cxx03/__coroutine/coroutine_handle.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COROUTINE_COROUTINE_HANDLE_H -#define _LIBCPP___COROUTINE_COROUTINE_HANDLE_H +#ifndef _LIBCPP___CXX03___COROUTINE_COROUTINE_HANDLE_H +#define _LIBCPP___CXX03___COROUTINE_COROUTINE_HANDLE_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -173,4 +173,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // __LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___COROUTINE_COROUTINE_HANDLE_H +#endif // _LIBCPP___CXX03___COROUTINE_COROUTINE_HANDLE_H diff --git a/libcxx/include/__cxx03/__coroutine/coroutine_traits.h b/libcxx/include/__cxx03/__coroutine/coroutine_traits.h index b4fc2f45a1ac4..2380b7a233910 100644 --- a/libcxx/include/__cxx03/__coroutine/coroutine_traits.h +++ b/libcxx/include/__cxx03/__coroutine/coroutine_traits.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COROUTINE_COROUTINE_TRAITS_H -#define _LIBCPP___COROUTINE_COROUTINE_TRAITS_H +#ifndef _LIBCPP___CXX03___COROUTINE_COROUTINE_TRAITS_H +#define _LIBCPP___CXX03___COROUTINE_COROUTINE_TRAITS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/void_t.h> @@ -45,4 +45,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // __LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___COROUTINE_COROUTINE_TRAITS_H +#endif // _LIBCPP___CXX03___COROUTINE_COROUTINE_TRAITS_H diff --git a/libcxx/include/__cxx03/__coroutine/noop_coroutine_handle.h b/libcxx/include/__cxx03/__coroutine/noop_coroutine_handle.h index 2a6e25cde2f68..c6ec745dbc2fc 100644 --- a/libcxx/include/__cxx03/__coroutine/noop_coroutine_handle.h +++ b/libcxx/include/__cxx03/__coroutine/noop_coroutine_handle.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H -#define _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H +#ifndef _LIBCPP___CXX03___COROUTINE_NOOP_COROUTINE_HANDLE_H +#define _LIBCPP___CXX03___COROUTINE_NOOP_COROUTINE_HANDLE_H #include <__cxx03/__config> #include <__cxx03/__coroutine/coroutine_handle.h> @@ -96,4 +96,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // __LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___COROUTINE_NOOP_COROUTINE_HANDLE_H +#endif // _LIBCPP___CXX03___COROUTINE_NOOP_COROUTINE_HANDLE_H diff --git a/libcxx/include/__cxx03/__coroutine/trivial_awaitables.h b/libcxx/include/__cxx03/__coroutine/trivial_awaitables.h index 9420824b6cefc..7e34aad9cfce8 100644 --- a/libcxx/include/__cxx03/__coroutine/trivial_awaitables.h +++ b/libcxx/include/__cxx03/__coroutine/trivial_awaitables.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H -#define __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H +#ifndef __LIBCPP___CXX03___COROUTINE_TRIVIAL_AWAITABLES_H +#define __LIBCPP___CXX03___COROUTINE_TRIVIAL_AWAITABLES_H #include <__cxx03/__config> #include <__cxx03/__coroutine/coroutine_handle.h> @@ -37,4 +37,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // __LIBCPP_STD_VER >= 20 -#endif // __LIBCPP___COROUTINE_TRIVIAL_AWAITABLES_H +#endif // __LIBCPP___CXX03___COROUTINE_TRIVIAL_AWAITABLES_H diff --git a/libcxx/include/__cxx03/__debug_utils/randomize_range.h b/libcxx/include/__cxx03/__debug_utils/randomize_range.h index 59e3a04f6d1ad..1baf4f5361ffd 100644 --- a/libcxx/include/__cxx03/__debug_utils/randomize_range.h +++ b/libcxx/include/__cxx03/__debug_utils/randomize_range.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LIBCXX_DEBUG_RANDOMIZE_RANGE_H -#define _LIBCPP___LIBCXX_DEBUG_RANDOMIZE_RANGE_H +#ifndef _LIBCPP___CXX03___LIBCXX_DEBUG_RANDOMIZE_RANGE_H +#define _LIBCPP___CXX03___LIBCXX_DEBUG_RANDOMIZE_RANGE_H #include <__cxx03/__config> @@ -39,4 +39,4 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __debug_randomize_range _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___LIBCXX_DEBUG_RANDOMIZE_RANGE_H +#endif // _LIBCPP___CXX03___LIBCXX_DEBUG_RANDOMIZE_RANGE_H diff --git a/libcxx/include/__cxx03/__debug_utils/sanitizers.h b/libcxx/include/__cxx03/__debug_utils/sanitizers.h index cd0caa9ed0a3f..e3cda20468b53 100644 --- a/libcxx/include/__cxx03/__debug_utils/sanitizers.h +++ b/libcxx/include/__cxx03/__debug_utils/sanitizers.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LIBCXX_DEBUG_UTILS_SANITIZERS_H -#define _LIBCPP___LIBCXX_DEBUG_UTILS_SANITIZERS_H +#ifndef _LIBCPP___CXX03___LIBCXX_DEBUG_UTILS_SANITIZERS_H +#define _LIBCPP___CXX03___LIBCXX_DEBUG_UTILS_SANITIZERS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/integral_constant.h> @@ -101,4 +101,4 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __annotate_contiguous_c _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___LIBCXX_DEBUG_UTILS_SANITIZERS_H +#endif // _LIBCPP___CXX03___LIBCXX_DEBUG_UTILS_SANITIZERS_H diff --git a/libcxx/include/__cxx03/__debug_utils/strict_weak_ordering_check.h b/libcxx/include/__cxx03/__debug_utils/strict_weak_ordering_check.h index 6aec78e46ff89..8d3a918d9b557 100644 --- a/libcxx/include/__cxx03/__debug_utils/strict_weak_ordering_check.h +++ b/libcxx/include/__cxx03/__debug_utils/strict_weak_ordering_check.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK -#define _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK +#ifndef _LIBCPP___CXX03___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK +#define _LIBCPP___CXX03___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK #include <__cxx03/__config> @@ -74,4 +74,4 @@ __check_strict_weak_ordering_sorted(_RandomAccessIterator __first, _RandomAccess _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK +#endif // _LIBCPP___CXX03___LIBCXX_DEBUG_STRICT_WEAK_ORDERING_CHECK diff --git a/libcxx/include/__cxx03/__exception/exception.h b/libcxx/include/__cxx03/__exception/exception.h index 8557cbd4945e4..27b1e4353ec46 100644 --- a/libcxx/include/__cxx03/__exception/exception.h +++ b/libcxx/include/__cxx03/__exception/exception.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___EXCEPTION_EXCEPTION_H -#define _LIBCPP___EXCEPTION_EXCEPTION_H +#ifndef _LIBCPP___CXX03___EXCEPTION_EXCEPTION_H +#define _LIBCPP___CXX03___EXCEPTION_EXCEPTION_H #include <__cxx03/__config> @@ -91,4 +91,4 @@ class _LIBCPP_EXPORTED_FROM_ABI bad_exception : public exception { } // namespace std -#endif // _LIBCPP___EXCEPTION_EXCEPTION_H +#endif // _LIBCPP___CXX03___EXCEPTION_EXCEPTION_H diff --git a/libcxx/include/__cxx03/__exception/exception_ptr.h b/libcxx/include/__cxx03/__exception/exception_ptr.h index 6bdb47fd395f0..33dbd40bef42c 100644 --- a/libcxx/include/__cxx03/__exception/exception_ptr.h +++ b/libcxx/include/__cxx03/__exception/exception_ptr.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___EXCEPTION_EXCEPTION_PTR_H -#define _LIBCPP___EXCEPTION_EXCEPTION_PTR_H +#ifndef _LIBCPP___CXX03___EXCEPTION_EXCEPTION_PTR_H +#define _LIBCPP___CXX03___EXCEPTION_EXCEPTION_PTR_H #include <__cxx03/__config> #include <__cxx03/__exception/operations.h> @@ -174,4 +174,4 @@ _LIBCPP_HIDE_FROM_ABI exception_ptr make_exception_ptr(_Ep __e) _NOEXCEPT { #endif // _LIBCPP_ABI_MICROSOFT } // namespace std -#endif // _LIBCPP___EXCEPTION_EXCEPTION_PTR_H +#endif // _LIBCPP___CXX03___EXCEPTION_EXCEPTION_PTR_H diff --git a/libcxx/include/__cxx03/__exception/nested_exception.h b/libcxx/include/__cxx03/__exception/nested_exception.h index 1b889e6bf5d87..60799942fb136 100644 --- a/libcxx/include/__cxx03/__exception/nested_exception.h +++ b/libcxx/include/__cxx03/__exception/nested_exception.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H -#define _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H +#ifndef _LIBCPP___CXX03___EXCEPTION_NESTED_EXCEPTION_H +#define _LIBCPP___CXX03___EXCEPTION_NESTED_EXCEPTION_H #include <__cxx03/__config> #include <__cxx03/__exception/exception_ptr.h> @@ -96,4 +96,4 @@ inline _LIBCPP_HIDE_FROM_ABI void rethrow_if_nested(const _Ep&) {} } // namespace std -#endif // _LIBCPP___EXCEPTION_NESTED_EXCEPTION_H +#endif // _LIBCPP___CXX03___EXCEPTION_NESTED_EXCEPTION_H diff --git a/libcxx/include/__cxx03/__exception/operations.h b/libcxx/include/__cxx03/__exception/operations.h index cb67194553d37..9049a0f313fae 100644 --- a/libcxx/include/__cxx03/__exception/operations.h +++ b/libcxx/include/__cxx03/__exception/operations.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___EXCEPTION_OPERATIONS_H -#define _LIBCPP___EXCEPTION_OPERATIONS_H +#ifndef _LIBCPP___CXX03___EXCEPTION_OPERATIONS_H +#define _LIBCPP___CXX03___EXCEPTION_OPERATIONS_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -38,4 +38,4 @@ _LIBCPP_EXPORTED_FROM_ABI exception_ptr current_exception() _NOEXCEPT; _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void rethrow_exception(exception_ptr); } // namespace std -#endif // _LIBCPP___EXCEPTION_OPERATIONS_H +#endif // _LIBCPP___CXX03___EXCEPTION_OPERATIONS_H diff --git a/libcxx/include/__cxx03/__exception/terminate.h b/libcxx/include/__cxx03/__exception/terminate.h index 78ccd16c91393..5f0cfa930f9af 100644 --- a/libcxx/include/__cxx03/__exception/terminate.h +++ b/libcxx/include/__cxx03/__exception/terminate.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___EXCEPTION_TERMINATE_H -#define _LIBCPP___EXCEPTION_TERMINATE_H +#ifndef _LIBCPP___CXX03___EXCEPTION_TERMINATE_H +#define _LIBCPP___CXX03___EXCEPTION_TERMINATE_H #include <__cxx03/__config> @@ -19,4 +19,4 @@ namespace std { // purposefully not using versioning namespace _LIBCPP_NORETURN _LIBCPP_EXPORTED_FROM_ABI void terminate() _NOEXCEPT; } // namespace std -#endif // _LIBCPP___EXCEPTION_TERMINATE_H +#endif // _LIBCPP___CXX03___EXCEPTION_TERMINATE_H diff --git a/libcxx/include/__cxx03/__expected/bad_expected_access.h b/libcxx/include/__cxx03/__expected/bad_expected_access.h index 4f7e33d2c6986..d9c64976c25b9 100644 --- a/libcxx/include/__cxx03/__expected/bad_expected_access.h +++ b/libcxx/include/__cxx03/__expected/bad_expected_access.h @@ -6,8 +6,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H -#define _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H +#ifndef _LIBCPP___CXX03___EXPECTED_BAD_EXPECTED_ACCESS_H +#define _LIBCPP___CXX03___EXPECTED_BAD_EXPECTED_ACCESS_H #include <__cxx03/__config> #include <__cxx03/__exception/exception.h> @@ -70,4 +70,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___EXPECTED_BAD_EXPECTED_ACCESS_H +#endif // _LIBCPP___CXX03___EXPECTED_BAD_EXPECTED_ACCESS_H diff --git a/libcxx/include/__cxx03/__expected/expected.h b/libcxx/include/__cxx03/__expected/expected.h index adadea8e4b39c..1d54bb9f6edeb 100644 --- a/libcxx/include/__cxx03/__expected/expected.h +++ b/libcxx/include/__cxx03/__expected/expected.h @@ -6,8 +6,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___EXPECTED_EXPECTED_H -#define _LIBCPP___EXPECTED_EXPECTED_H +#ifndef _LIBCPP___CXX03___EXPECTED_EXPECTED_H +#define _LIBCPP___CXX03___EXPECTED_EXPECTED_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -1871,4 +1871,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___EXPECTED_EXPECTED_H +#endif // _LIBCPP___CXX03___EXPECTED_EXPECTED_H diff --git a/libcxx/include/__cxx03/__expected/unexpect.h b/libcxx/include/__cxx03/__expected/unexpect.h index 895f053a1e333..d8de027cabc5b 100644 --- a/libcxx/include/__cxx03/__expected/unexpect.h +++ b/libcxx/include/__cxx03/__expected/unexpect.h @@ -6,8 +6,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___EXPECTED_UNEXPECT_H -#define _LIBCPP___EXPECTED_UNEXPECT_H +#ifndef _LIBCPP___CXX03___EXPECTED_UNEXPECT_H +#define _LIBCPP___CXX03___EXPECTED_UNEXPECT_H #include <__cxx03/__config> @@ -29,4 +29,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 23 -#endif // _LIBCPP___EXPECTED_UNEXPECT_H +#endif // _LIBCPP___CXX03___EXPECTED_UNEXPECT_H diff --git a/libcxx/include/__cxx03/__expected/unexpected.h b/libcxx/include/__cxx03/__expected/unexpected.h index fe2ab407b4151..bafa33a011eea 100644 --- a/libcxx/include/__cxx03/__expected/unexpected.h +++ b/libcxx/include/__cxx03/__expected/unexpected.h @@ -6,8 +6,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___EXPECTED_UNEXPECTED_H -#define _LIBCPP___EXPECTED_UNEXPECTED_H +#ifndef _LIBCPP___CXX03___EXPECTED_UNEXPECTED_H +#define _LIBCPP___CXX03___EXPECTED_UNEXPECTED_H #include <__cxx03/__config> #include <__cxx03/__type_traits/conjunction.h> @@ -124,4 +124,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___EXPECTED_UNEXPECTED_H +#endif // _LIBCPP___CXX03___EXPECTED_UNEXPECTED_H diff --git a/libcxx/include/__cxx03/__filesystem/copy_options.h b/libcxx/include/__cxx03/__filesystem/copy_options.h index c9adf3cd64eb4..01abb5042b7e4 100644 --- a/libcxx/include/__cxx03/__filesystem/copy_options.h +++ b/libcxx/include/__cxx03/__filesystem/copy_options.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_COPY_OPTIONS_H -#define _LIBCPP___FILESYSTEM_COPY_OPTIONS_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_COPY_OPTIONS_H +#define _LIBCPP___CXX03___FILESYSTEM_COPY_OPTIONS_H #include <__cxx03/__config> @@ -66,4 +66,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___FILESYSTEM_COPY_OPTIONS_H +#endif // _LIBCPP___CXX03___FILESYSTEM_COPY_OPTIONS_H diff --git a/libcxx/include/__cxx03/__filesystem/directory_entry.h b/libcxx/include/__cxx03/__filesystem/directory_entry.h index a78f43d6b1c5c..1a8ebf470bf89 100644 --- a/libcxx/include/__cxx03/__filesystem/directory_entry.h +++ b/libcxx/include/__cxx03/__filesystem/directory_entry.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H -#define _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_DIRECTORY_ENTRY_H +#define _LIBCPP___CXX03___FILESYSTEM_DIRECTORY_ENTRY_H #include <__cxx03/__chrono/time_point.h> #include <__cxx03/__compare/ordering.h> @@ -432,4 +432,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM _LIBCPP_POP_MACROS -#endif // _LIBCPP___FILESYSTEM_DIRECTORY_ENTRY_H +#endif // _LIBCPP___CXX03___FILESYSTEM_DIRECTORY_ENTRY_H diff --git a/libcxx/include/__cxx03/__filesystem/directory_iterator.h b/libcxx/include/__cxx03/__filesystem/directory_iterator.h index 667007f5c2cdf..226ef7a27f942 100644 --- a/libcxx/include/__cxx03/__filesystem/directory_iterator.h +++ b/libcxx/include/__cxx03/__filesystem/directory_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H -#define _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_DIRECTORY_ITERATOR_H +#define _LIBCPP___CXX03___FILESYSTEM_DIRECTORY_ITERATOR_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -148,4 +148,4 @@ _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool _LIBCPP_POP_MACROS -#endif // _LIBCPP___FILESYSTEM_DIRECTORY_ITERATOR_H +#endif // _LIBCPP___CXX03___FILESYSTEM_DIRECTORY_ITERATOR_H diff --git a/libcxx/include/__cxx03/__filesystem/directory_options.h b/libcxx/include/__cxx03/__filesystem/directory_options.h index eeb87936f2bd1..babdf9c911bee 100644 --- a/libcxx/include/__cxx03/__filesystem/directory_options.h +++ b/libcxx/include/__cxx03/__filesystem/directory_options.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H -#define _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_DIRECTORY_OPTIONS_H +#define _LIBCPP___CXX03___FILESYSTEM_DIRECTORY_OPTIONS_H #include <__cxx03/__config> @@ -54,4 +54,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___FILESYSTEM_DIRECTORY_OPTIONS_H +#endif // _LIBCPP___CXX03___FILESYSTEM_DIRECTORY_OPTIONS_H diff --git a/libcxx/include/__cxx03/__filesystem/file_status.h b/libcxx/include/__cxx03/__filesystem/file_status.h index 0022518842af7..1e5ea497434d9 100644 --- a/libcxx/include/__cxx03/__filesystem/file_status.h +++ b/libcxx/include/__cxx03/__filesystem/file_status.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_FILE_STATUS_H -#define _LIBCPP___FILESYSTEM_FILE_STATUS_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_FILE_STATUS_H +#define _LIBCPP___CXX03___FILESYSTEM_FILE_STATUS_H #include <__cxx03/__config> #include <__cxx03/__filesystem/file_type.h> @@ -64,4 +64,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___FILESYSTEM_FILE_STATUS_H +#endif // _LIBCPP___CXX03___FILESYSTEM_FILE_STATUS_H diff --git a/libcxx/include/__cxx03/__filesystem/file_time_type.h b/libcxx/include/__cxx03/__filesystem/file_time_type.h index 1e964bbe32522..cd52453b0b879 100644 --- a/libcxx/include/__cxx03/__filesystem/file_time_type.h +++ b/libcxx/include/__cxx03/__filesystem/file_time_type.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H -#define _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_FILE_TIME_TYPE_H +#define _LIBCPP___CXX03___FILESYSTEM_FILE_TIME_TYPE_H #include <__cxx03/__chrono/file_clock.h> #include <__cxx03/__chrono/time_point.h> @@ -28,4 +28,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___FILESYSTEM_FILE_TIME_TYPE_H +#endif // _LIBCPP___CXX03___FILESYSTEM_FILE_TIME_TYPE_H diff --git a/libcxx/include/__cxx03/__filesystem/file_type.h b/libcxx/include/__cxx03/__filesystem/file_type.h index 392ca2b57c26b..34f0aba307128 100644 --- a/libcxx/include/__cxx03/__filesystem/file_type.h +++ b/libcxx/include/__cxx03/__filesystem/file_type.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_FILE_TYPE_H -#define _LIBCPP___FILESYSTEM_FILE_TYPE_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_FILE_TYPE_H +#define _LIBCPP___CXX03___FILESYSTEM_FILE_TYPE_H #include <__cxx03/__config> @@ -39,4 +39,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___FILESYSTEM_FILE_TYPE_H +#endif // _LIBCPP___CXX03___FILESYSTEM_FILE_TYPE_H diff --git a/libcxx/include/__cxx03/__filesystem/filesystem_error.h b/libcxx/include/__cxx03/__filesystem/filesystem_error.h index 8b68bac2e36fa..ef9e0d7846436 100644 --- a/libcxx/include/__cxx03/__filesystem/filesystem_error.h +++ b/libcxx/include/__cxx03/__filesystem/filesystem_error.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H -#define _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_FILESYSTEM_ERROR_H +#define _LIBCPP___CXX03___FILESYSTEM_FILESYSTEM_ERROR_H #include <__cxx03/__config> #include <__cxx03/__filesystem/path.h> @@ -85,4 +85,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___FILESYSTEM_FILESYSTEM_ERROR_H +#endif // _LIBCPP___CXX03___FILESYSTEM_FILESYSTEM_ERROR_H diff --git a/libcxx/include/__cxx03/__filesystem/operations.h b/libcxx/include/__cxx03/__filesystem/operations.h index 90b90bbaace93..fdb3dab858f50 100644 --- a/libcxx/include/__cxx03/__filesystem/operations.h +++ b/libcxx/include/__cxx03/__filesystem/operations.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_OPERATIONS_H -#define _LIBCPP___FILESYSTEM_OPERATIONS_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_OPERATIONS_H +#define _LIBCPP___CXX03___FILESYSTEM_OPERATIONS_H #include <__cxx03/__chrono/time_point.h> #include <__cxx03/__config> @@ -307,4 +307,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // _LIBCPP_STD_VER >= 17 && !defined(_LIBCPP_HAS_NO_FILESYSTEM) -#endif // _LIBCPP___FILESYSTEM_OPERATIONS_H +#endif // _LIBCPP___CXX03___FILESYSTEM_OPERATIONS_H diff --git a/libcxx/include/__cxx03/__filesystem/path.h b/libcxx/include/__cxx03/__filesystem/path.h index 815d881d8a099..e5eed68e4d6c4 100644 --- a/libcxx/include/__cxx03/__filesystem/path.h +++ b/libcxx/include/__cxx03/__filesystem/path.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_PATH_H -#define _LIBCPP___FILESYSTEM_PATH_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_PATH_H +#define _LIBCPP___CXX03___FILESYSTEM_PATH_H #include <__cxx03/__algorithm/replace.h> #include <__cxx03/__algorithm/replace_copy.h> @@ -928,4 +928,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FILESYSTEM_PATH_H +#endif // _LIBCPP___CXX03___FILESYSTEM_PATH_H diff --git a/libcxx/include/__cxx03/__filesystem/path_iterator.h b/libcxx/include/__cxx03/__filesystem/path_iterator.h index c439782a2a6af..121626b4b6ca0 100644 --- a/libcxx/include/__cxx03/__filesystem/path_iterator.h +++ b/libcxx/include/__cxx03/__filesystem/path_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_PATH_ITERATOR_H -#define _LIBCPP___FILESYSTEM_PATH_ITERATOR_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_PATH_ITERATOR_H +#define _LIBCPP___CXX03___FILESYSTEM_PATH_ITERATOR_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -112,4 +112,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___FILESYSTEM_PATH_ITERATOR_H +#endif // _LIBCPP___CXX03___FILESYSTEM_PATH_ITERATOR_H diff --git a/libcxx/include/__cxx03/__filesystem/perm_options.h b/libcxx/include/__cxx03/__filesystem/perm_options.h index bfd7941cf1003..bebb3038bf6eb 100644 --- a/libcxx/include/__cxx03/__filesystem/perm_options.h +++ b/libcxx/include/__cxx03/__filesystem/perm_options.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_PERM_OPTIONS_H -#define _LIBCPP___FILESYSTEM_PERM_OPTIONS_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_PERM_OPTIONS_H +#define _LIBCPP___CXX03___FILESYSTEM_PERM_OPTIONS_H #include <__cxx03/__config> @@ -54,4 +54,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___FILESYSTEM_PERM_OPTIONS_H +#endif // _LIBCPP___CXX03___FILESYSTEM_PERM_OPTIONS_H diff --git a/libcxx/include/__cxx03/__filesystem/perms.h b/libcxx/include/__cxx03/__filesystem/perms.h index d14023730938c..139352c3a8f89 100644 --- a/libcxx/include/__cxx03/__filesystem/perms.h +++ b/libcxx/include/__cxx03/__filesystem/perms.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_PERMS_H -#define _LIBCPP___FILESYSTEM_PERMS_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_PERMS_H +#define _LIBCPP___CXX03___FILESYSTEM_PERMS_H #include <__cxx03/__config> @@ -77,4 +77,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___FILESYSTEM_PERMS_H +#endif // _LIBCPP___CXX03___FILESYSTEM_PERMS_H diff --git a/libcxx/include/__cxx03/__filesystem/recursive_directory_iterator.h b/libcxx/include/__cxx03/__filesystem/recursive_directory_iterator.h index 43da731cc5b9c..a459bd3db4bb2 100644 --- a/libcxx/include/__cxx03/__filesystem/recursive_directory_iterator.h +++ b/libcxx/include/__cxx03/__filesystem/recursive_directory_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H -#define _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H +#define _LIBCPP___CXX03___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H #include <__cxx03/__config> #include <__cxx03/__filesystem/directory_entry.h> @@ -161,4 +161,4 @@ _LIBCPP_AVAILABILITY_FILESYSTEM_LIBRARY inline constexpr bool _LIBCPP_POP_MACROS -#endif // _LIBCPP___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H +#endif // _LIBCPP___CXX03___FILESYSTEM_RECURSIVE_DIRECTORY_ITERATOR_H diff --git a/libcxx/include/__cxx03/__filesystem/space_info.h b/libcxx/include/__cxx03/__filesystem/space_info.h index 8e2f260249793..0a998f87329a8 100644 --- a/libcxx/include/__cxx03/__filesystem/space_info.h +++ b/libcxx/include/__cxx03/__filesystem/space_info.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_SPACE_INFO_H -#define _LIBCPP___FILESYSTEM_SPACE_INFO_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_SPACE_INFO_H +#define _LIBCPP___CXX03___FILESYSTEM_SPACE_INFO_H #include <__cxx03/__config> #include <__cxx03/cstdint> @@ -35,4 +35,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___FILESYSTEM_SPACE_INFO_H +#endif // _LIBCPP___CXX03___FILESYSTEM_SPACE_INFO_H diff --git a/libcxx/include/__cxx03/__filesystem/u8path.h b/libcxx/include/__cxx03/__filesystem/u8path.h index 7f1fe89bf2522..f60ef6a83f5cc 100644 --- a/libcxx/include/__cxx03/__filesystem/u8path.h +++ b/libcxx/include/__cxx03/__filesystem/u8path.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FILESYSTEM_U8PATH_H -#define _LIBCPP___FILESYSTEM_U8PATH_H +#ifndef _LIBCPP___CXX03___FILESYSTEM_U8PATH_H +#define _LIBCPP___CXX03___FILESYSTEM_U8PATH_H #include <__cxx03/__algorithm/unwrap_iter.h> #include <__cxx03/__config> @@ -97,4 +97,4 @@ _LIBCPP_END_NAMESPACE_FILESYSTEM #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___FILESYSTEM_U8PATH_H +#endif // _LIBCPP___CXX03___FILESYSTEM_U8PATH_H diff --git a/libcxx/include/__cxx03/__format/buffer.h b/libcxx/include/__cxx03/__format/buffer.h index d4162086b84f4..167b06d7fd226 100644 --- a/libcxx/include/__cxx03/__format/buffer.h +++ b/libcxx/include/__cxx03/__format/buffer.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_BUFFER_H -#define _LIBCPP___FORMAT_BUFFER_H +#ifndef _LIBCPP___CXX03___FORMAT_BUFFER_H +#define _LIBCPP___CXX03___FORMAT_BUFFER_H #include <__cxx03/__algorithm/copy_n.h> #include <__cxx03/__algorithm/fill_n.h> @@ -652,4 +652,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FORMAT_BUFFER_H +#endif // _LIBCPP___CXX03___FORMAT_BUFFER_H diff --git a/libcxx/include/__cxx03/__format/concepts.h b/libcxx/include/__cxx03/__format/concepts.h index ffe937e207ffe..90fcb7ed0b8f6 100644 --- a/libcxx/include/__cxx03/__format/concepts.h +++ b/libcxx/include/__cxx03/__format/concepts.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_CONCEPTS_H -#define _LIBCPP___FORMAT_CONCEPTS_H +#ifndef _LIBCPP___CXX03___FORMAT_CONCEPTS_H +#define _LIBCPP___CXX03___FORMAT_CONCEPTS_H #include <__cxx03/__concepts/same_as.h> #include <__cxx03/__concepts/semiregular.h> @@ -80,4 +80,4 @@ concept __fmt_pair_like = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_CONCEPTS_H +#endif // _LIBCPP___CXX03___FORMAT_CONCEPTS_H diff --git a/libcxx/include/__cxx03/__format/container_adaptor.h b/libcxx/include/__cxx03/__format/container_adaptor.h index 5d47677d8d537..42c0d14be61a8 100644 --- a/libcxx/include/__cxx03/__format/container_adaptor.h +++ b/libcxx/include/__cxx03/__format/container_adaptor.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H -#define _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H +#ifndef _LIBCPP___CXX03___FORMAT_CONTAINER_ADAPTOR_H +#define _LIBCPP___CXX03___FORMAT_CONTAINER_ADAPTOR_H #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -70,4 +70,4 @@ struct _LIBCPP_TEMPLATE_VIS formatter, _CharT> _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_CONTAINER_ADAPTOR_H +#endif // _LIBCPP___CXX03___FORMAT_CONTAINER_ADAPTOR_H diff --git a/libcxx/include/__cxx03/__format/enable_insertable.h b/libcxx/include/__cxx03/__format/enable_insertable.h index 8bcae600a54ea..d52ca8cfd442c 100644 --- a/libcxx/include/__cxx03/__format/enable_insertable.h +++ b/libcxx/include/__cxx03/__format/enable_insertable.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_ENABLE_INSERTABLE_H -#define _LIBCPP___FORMAT_ENABLE_INSERTABLE_H +#ifndef _LIBCPP___CXX03___FORMAT_ENABLE_INSERTABLE_H +#define _LIBCPP___CXX03___FORMAT_ENABLE_INSERTABLE_H #include <__cxx03/__config> @@ -32,4 +32,4 @@ inline constexpr bool __enable_insertable = false; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_ENABLE_INSERTABLE_H +#endif // _LIBCPP___CXX03___FORMAT_ENABLE_INSERTABLE_H diff --git a/libcxx/include/__cxx03/__format/escaped_output_table.h b/libcxx/include/__cxx03/__format/escaped_output_table.h index 0039968566f88..c5142849865ba 100644 --- a/libcxx/include/__cxx03/__format/escaped_output_table.h +++ b/libcxx/include/__cxx03/__format/escaped_output_table.h @@ -58,8 +58,8 @@ // use or other dealings in these Data Files or Software without prior // written authorization of the copyright holder. -#ifndef _LIBCPP___FORMAT_ESCAPED_OUTPUT_TABLE_H -#define _LIBCPP___FORMAT_ESCAPED_OUTPUT_TABLE_H +#ifndef _LIBCPP___CXX03___FORMAT_ESCAPED_OUTPUT_TABLE_H +#define _LIBCPP___CXX03___FORMAT_ESCAPED_OUTPUT_TABLE_H #include <__cxx03/__algorithm/ranges_upper_bound.h> #include <__cxx03/__config> @@ -860,4 +860,4 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[711] = { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_ESCAPED_OUTPUT_TABLE_H +#endif // _LIBCPP___CXX03___FORMAT_ESCAPED_OUTPUT_TABLE_H diff --git a/libcxx/include/__cxx03/__format/extended_grapheme_cluster_table.h b/libcxx/include/__cxx03/__format/extended_grapheme_cluster_table.h index d83838bbc83a7..c26b870d30378 100644 --- a/libcxx/include/__cxx03/__format/extended_grapheme_cluster_table.h +++ b/libcxx/include/__cxx03/__format/extended_grapheme_cluster_table.h @@ -58,8 +58,8 @@ // use or other dealings in these Data Files or Software without prior // written authorization of the copyright holder. -#ifndef _LIBCPP___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H -#define _LIBCPP___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H +#ifndef _LIBCPP___CXX03___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H +#define _LIBCPP___CXX03___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H #include <__cxx03/__algorithm/ranges_upper_bound.h> #include <__cxx03/__config> @@ -1660,4 +1660,4 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[1496] = { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H +#endif // _LIBCPP___CXX03___FORMAT_EXTENDED_GRAPHEME_CLUSTER_TABLE_H diff --git a/libcxx/include/__cxx03/__format/format_arg.h b/libcxx/include/__cxx03/__format/format_arg.h index 3d37555c0e2df..cf9bf75e60df9 100644 --- a/libcxx/include/__cxx03/__format/format_arg.h +++ b/libcxx/include/__cxx03/__format/format_arg.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMAT_ARG_H -#define _LIBCPP___FORMAT_FORMAT_ARG_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMAT_ARG_H +#define _LIBCPP___CXX03___FORMAT_FORMAT_ARG_H #include <__cxx03/__assert> #include <__cxx03/__concepts/arithmetic.h> @@ -398,4 +398,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FORMAT_FORMAT_ARG_H +#endif // _LIBCPP___CXX03___FORMAT_FORMAT_ARG_H diff --git a/libcxx/include/__cxx03/__format/format_arg_store.h b/libcxx/include/__cxx03/__format/format_arg_store.h index 836a5a2ffc456..1116b53edc20c 100644 --- a/libcxx/include/__cxx03/__format/format_arg_store.h +++ b/libcxx/include/__cxx03/__format/format_arg_store.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMAT_ARG_STORE_H -#define _LIBCPP___FORMAT_FORMAT_ARG_STORE_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMAT_ARG_STORE_H +#define _LIBCPP___CXX03___FORMAT_FORMAT_ARG_STORE_H #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -263,4 +263,4 @@ struct _LIBCPP_TEMPLATE_VIS __format_arg_store { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMAT_ARG_STORE_H +#endif // _LIBCPP___CXX03___FORMAT_FORMAT_ARG_STORE_H diff --git a/libcxx/include/__cxx03/__format/format_args.h b/libcxx/include/__cxx03/__format/format_args.h index 494ba91cf55ae..702b8763d31e5 100644 --- a/libcxx/include/__cxx03/__format/format_args.h +++ b/libcxx/include/__cxx03/__format/format_args.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMAT_ARGS_H -#define _LIBCPP___FORMAT_FORMAT_ARGS_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMAT_ARGS_H +#define _LIBCPP___CXX03___FORMAT_FORMAT_ARGS_H #include <__cxx03/__config> #include <__cxx03/__format/format_arg.h> @@ -75,4 +75,4 @@ basic_format_args(__format_arg_store<_Context, _Args...>) -> basic_format_args<_ _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMAT_ARGS_H +#endif // _LIBCPP___CXX03___FORMAT_FORMAT_ARGS_H diff --git a/libcxx/include/__cxx03/__format/format_context.h b/libcxx/include/__cxx03/__format/format_context.h index 04f2d69a247db..7f1011581133b 100644 --- a/libcxx/include/__cxx03/__format/format_context.h +++ b/libcxx/include/__cxx03/__format/format_context.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMAT_CONTEXT_H -#define _LIBCPP___FORMAT_FORMAT_CONTEXT_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMAT_CONTEXT_H +#define _LIBCPP___CXX03___FORMAT_FORMAT_CONTEXT_H #include <__cxx03/__concepts/same_as.h> #include <__cxx03/__config> @@ -217,4 +217,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FORMAT_FORMAT_CONTEXT_H +#endif // _LIBCPP___CXX03___FORMAT_FORMAT_CONTEXT_H diff --git a/libcxx/include/__cxx03/__format/format_error.h b/libcxx/include/__cxx03/__format/format_error.h index 701bf3ad0dcc5..c0a2959131e48 100644 --- a/libcxx/include/__cxx03/__format/format_error.h +++ b/libcxx/include/__cxx03/__format/format_error.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMAT_ERROR_H -#define _LIBCPP___FORMAT_FORMAT_ERROR_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMAT_ERROR_H +#define _LIBCPP___CXX03___FORMAT_FORMAT_ERROR_H #include <__cxx03/__config> #include <__cxx03/__verbose_abort> @@ -47,4 +47,4 @@ _LIBCPP_NORETURN inline _LIBCPP_HIDE_FROM_ABI void __throw_format_error(const ch _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMAT_ERROR_H +#endif // _LIBCPP___CXX03___FORMAT_FORMAT_ERROR_H diff --git a/libcxx/include/__cxx03/__format/format_functions.h b/libcxx/include/__cxx03/__format/format_functions.h index bc9056dd0bdeb..d3a1bc46c8a7d 100644 --- a/libcxx/include/__cxx03/__format/format_functions.h +++ b/libcxx/include/__cxx03/__format/format_functions.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMAT_FUNCTIONS -#define _LIBCPP___FORMAT_FORMAT_FUNCTIONS +#ifndef _LIBCPP___CXX03___FORMAT_FORMAT_FUNCTIONS +#define _LIBCPP___CXX03___FORMAT_FORMAT_FUNCTIONS #include <__cxx03/__algorithm/clamp.h> #include <__cxx03/__concepts/convertible_to.h> @@ -677,4 +677,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FORMAT_FORMAT_FUNCTIONS +#endif // _LIBCPP___CXX03___FORMAT_FORMAT_FUNCTIONS diff --git a/libcxx/include/__cxx03/__format/format_parse_context.h b/libcxx/include/__cxx03/__format/format_parse_context.h index 1df545987659b..81338506aee69 100644 --- a/libcxx/include/__cxx03/__format/format_parse_context.h +++ b/libcxx/include/__cxx03/__format/format_parse_context.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H -#define _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMAT_PARSE_CONTEXT_H +#define _LIBCPP___CXX03___FORMAT_FORMAT_PARSE_CONTEXT_H #include <__cxx03/__config> #include <__cxx03/__format/format_error.h> @@ -102,4 +102,4 @@ using wformat_parse_context = basic_format_parse_context; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMAT_PARSE_CONTEXT_H +#endif // _LIBCPP___CXX03___FORMAT_FORMAT_PARSE_CONTEXT_H diff --git a/libcxx/include/__cxx03/__format/format_string.h b/libcxx/include/__cxx03/__format/format_string.h index c48719337372d..6a7276419167a 100644 --- a/libcxx/include/__cxx03/__format/format_string.h +++ b/libcxx/include/__cxx03/__format/format_string.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMAT_STRING_H -#define _LIBCPP___FORMAT_FORMAT_STRING_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMAT_STRING_H +#define _LIBCPP___CXX03___FORMAT_FORMAT_STRING_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -157,4 +157,4 @@ __parse_arg_id(_Iterator __begin, _Iterator __end, auto& __parse_ctx) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMAT_STRING_H +#endif // _LIBCPP___CXX03___FORMAT_FORMAT_STRING_H diff --git a/libcxx/include/__cxx03/__format/format_to_n_result.h b/libcxx/include/__cxx03/__format/format_to_n_result.h index 8797432922eb9..65e7031f57648 100644 --- a/libcxx/include/__cxx03/__format/format_to_n_result.h +++ b/libcxx/include/__cxx03/__format/format_to_n_result.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMAT_TO_N_RESULT_H -#define _LIBCPP___FORMAT_FORMAT_TO_N_RESULT_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMAT_TO_N_RESULT_H +#define _LIBCPP___CXX03___FORMAT_FORMAT_TO_N_RESULT_H #include <__cxx03/__config> #include <__cxx03/__iterator/incrementable_traits.h> @@ -32,4 +32,4 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(format_to_n_result); _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMAT_TO_N_RESULT_H +#endif // _LIBCPP___CXX03___FORMAT_FORMAT_TO_N_RESULT_H diff --git a/libcxx/include/__cxx03/__format/formatter.h b/libcxx/include/__cxx03/__format/formatter.h index 98457d0a2c65e..9afc9dfce3cb5 100644 --- a/libcxx/include/__cxx03/__format/formatter.h +++ b/libcxx/include/__cxx03/__format/formatter.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMATTER_H -#define _LIBCPP___FORMAT_FORMATTER_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMATTER_H +#define _LIBCPP___CXX03___FORMAT_FORMATTER_H #include <__cxx03/__config> #include <__cxx03/__fwd/format.h> @@ -50,4 +50,4 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __set_debug_format(_Tp& __formatter) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMATTER_H +#endif // _LIBCPP___CXX03___FORMAT_FORMATTER_H diff --git a/libcxx/include/__cxx03/__format/formatter_bool.h b/libcxx/include/__cxx03/__format/formatter_bool.h index dd8e97bfc7f48..12a29c2c56040 100644 --- a/libcxx/include/__cxx03/__format/formatter_bool.h +++ b/libcxx/include/__cxx03/__format/formatter_bool.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMATTER_BOOL_H -#define _LIBCPP___FORMAT_FORMATTER_BOOL_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMATTER_BOOL_H +#define _LIBCPP___CXX03___FORMAT_FORMATTER_BOOL_H #include <__cxx03/__algorithm/copy.h> #include <__cxx03/__assert> @@ -73,4 +73,4 @@ struct _LIBCPP_TEMPLATE_VIS formatter { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMATTER_BOOL_H +#endif // _LIBCPP___CXX03___FORMAT_FORMATTER_BOOL_H diff --git a/libcxx/include/__cxx03/__format/formatter_char.h b/libcxx/include/__cxx03/__format/formatter_char.h index b743433c2891d..f0a7d153ea343 100644 --- a/libcxx/include/__cxx03/__format/formatter_char.h +++ b/libcxx/include/__cxx03/__format/formatter_char.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMATTER_CHAR_H -#define _LIBCPP___FORMAT_FORMATTER_CHAR_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMATTER_CHAR_H +#define _LIBCPP___CXX03___FORMAT_FORMATTER_CHAR_H #include <__cxx03/__concepts/same_as.h> #include <__cxx03/__config> @@ -90,4 +90,4 @@ struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_cha _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMATTER_CHAR_H +#endif // _LIBCPP___CXX03___FORMAT_FORMATTER_CHAR_H diff --git a/libcxx/include/__cxx03/__format/formatter_floating_point.h b/libcxx/include/__cxx03/__format/formatter_floating_point.h index 36663fb90716b..9f7eec0addcf2 100644 --- a/libcxx/include/__cxx03/__format/formatter_floating_point.h +++ b/libcxx/include/__cxx03/__format/formatter_floating_point.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H -#define _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMATTER_FLOATING_POINT_H +#define _LIBCPP___CXX03___FORMAT_FORMATTER_FLOATING_POINT_H #include <__cxx03/__algorithm/copy_n.h> #include <__cxx03/__algorithm/find.h> @@ -780,4 +780,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FORMAT_FORMATTER_FLOATING_POINT_H +#endif // _LIBCPP___CXX03___FORMAT_FORMATTER_FLOATING_POINT_H diff --git a/libcxx/include/__cxx03/__format/formatter_integer.h b/libcxx/include/__cxx03/__format/formatter_integer.h index 0d4dd15de4f9d..365b44093ede2 100644 --- a/libcxx/include/__cxx03/__format/formatter_integer.h +++ b/libcxx/include/__cxx03/__format/formatter_integer.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMATTER_INTEGER_H -#define _LIBCPP___FORMAT_FORMATTER_INTEGER_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMATTER_INTEGER_H +#define _LIBCPP___CXX03___FORMAT_FORMATTER_INTEGER_H #include <__cxx03/__concepts/arithmetic.h> #include <__cxx03/__config> @@ -92,4 +92,4 @@ struct _LIBCPP_TEMPLATE_VIS formatter<__uint128_t, _CharT> : public __formatter_ _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMATTER_INTEGER_H +#endif // _LIBCPP___CXX03___FORMAT_FORMATTER_INTEGER_H diff --git a/libcxx/include/__cxx03/__format/formatter_integral.h b/libcxx/include/__cxx03/__format/formatter_integral.h index 6bab831244498..fc846549dabdc 100644 --- a/libcxx/include/__cxx03/__format/formatter_integral.h +++ b/libcxx/include/__cxx03/__format/formatter_integral.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H -#define _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMATTER_INTEGRAL_H +#define _LIBCPP___CXX03___FORMAT_FORMATTER_INTEGRAL_H #include <__cxx03/__charconv/to_chars_integral.h> #include <__cxx03/__charconv/to_chars_result.h> @@ -442,4 +442,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FORMAT_FORMATTER_INTEGRAL_H +#endif // _LIBCPP___CXX03___FORMAT_FORMATTER_INTEGRAL_H diff --git a/libcxx/include/__cxx03/__format/formatter_output.h b/libcxx/include/__cxx03/__format/formatter_output.h index edf6909de750a..1f3ab7f2ff692 100644 --- a/libcxx/include/__cxx03/__format/formatter_output.h +++ b/libcxx/include/__cxx03/__format/formatter_output.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMATTER_OUTPUT_H -#define _LIBCPP___FORMAT_FORMATTER_OUTPUT_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMATTER_OUTPUT_H +#define _LIBCPP___CXX03___FORMAT_FORMATTER_OUTPUT_H #include <__cxx03/__algorithm/ranges_copy.h> #include <__cxx03/__algorithm/ranges_fill_n.h> @@ -332,4 +332,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FORMAT_FORMATTER_OUTPUT_H +#endif // _LIBCPP___CXX03___FORMAT_FORMATTER_OUTPUT_H diff --git a/libcxx/include/__cxx03/__format/formatter_pointer.h b/libcxx/include/__cxx03/__format/formatter_pointer.h index 166a2e93b622f..906d62a83e33b 100644 --- a/libcxx/include/__cxx03/__format/formatter_pointer.h +++ b/libcxx/include/__cxx03/__format/formatter_pointer.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMATTER_POINTER_H -#define _LIBCPP___FORMAT_FORMATTER_POINTER_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMATTER_POINTER_H +#define _LIBCPP___CXX03___FORMAT_FORMATTER_POINTER_H #include <__cxx03/__config> #include <__cxx03/__format/concepts.h> @@ -69,4 +69,4 @@ struct _LIBCPP_TEMPLATE_VIS formatter : public __formatter_ _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMATTER_POINTER_H +#endif // _LIBCPP___CXX03___FORMAT_FORMATTER_POINTER_H diff --git a/libcxx/include/__cxx03/__format/formatter_string.h b/libcxx/include/__cxx03/__format/formatter_string.h index 9cc862a4545c7..024f7936875ec 100644 --- a/libcxx/include/__cxx03/__format/formatter_string.h +++ b/libcxx/include/__cxx03/__format/formatter_string.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMATTER_STRING_H -#define _LIBCPP___FORMAT_FORMATTER_STRING_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMATTER_STRING_H +#define _LIBCPP___CXX03___FORMAT_FORMATTER_STRING_H #include <__cxx03/__config> #include <__cxx03/__format/concepts.h> @@ -147,4 +147,4 @@ struct _LIBCPP_TEMPLATE_VIS formatter, _CharT _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMATTER_STRING_H +#endif // _LIBCPP___CXX03___FORMAT_FORMATTER_STRING_H diff --git a/libcxx/include/__cxx03/__format/formatter_tuple.h b/libcxx/include/__cxx03/__format/formatter_tuple.h index 911552f663505..0a5ce4e070a64 100644 --- a/libcxx/include/__cxx03/__format/formatter_tuple.h +++ b/libcxx/include/__cxx03/__format/formatter_tuple.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_FORMATTER_TUPLE_H -#define _LIBCPP___FORMAT_FORMATTER_TUPLE_H +#ifndef _LIBCPP___CXX03___FORMAT_FORMATTER_TUPLE_H +#define _LIBCPP___CXX03___FORMAT_FORMATTER_TUPLE_H #include <__cxx03/__algorithm/ranges_copy.h> #include <__cxx03/__chrono/statically_widen.h> @@ -147,4 +147,4 @@ struct _LIBCPP_TEMPLATE_VIS formatter, _CharT> _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_FORMATTER_TUPLE_H +#endif // _LIBCPP___CXX03___FORMAT_FORMATTER_TUPLE_H diff --git a/libcxx/include/__cxx03/__format/indic_conjunct_break_table.h b/libcxx/include/__cxx03/__format/indic_conjunct_break_table.h index b02c2c324573c..37fbde2998736 100644 --- a/libcxx/include/__cxx03/__format/indic_conjunct_break_table.h +++ b/libcxx/include/__cxx03/__format/indic_conjunct_break_table.h @@ -58,8 +58,8 @@ // use or other dealings in these Data Files or Software without prior // written authorization of the copyright holder. -#ifndef _LIBCPP___FORMAT_INDIC_CONJUNCT_BREAK_TABLE_H -#define _LIBCPP___FORMAT_INDIC_CONJUNCT_BREAK_TABLE_H +#ifndef _LIBCPP___CXX03___FORMAT_INDIC_CONJUNCT_BREAK_TABLE_H +#define _LIBCPP___CXX03___FORMAT_INDIC_CONJUNCT_BREAK_TABLE_H #include <__cxx03/__algorithm/ranges_upper_bound.h> #include <__cxx03/__config> @@ -347,4 +347,4 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr uint32_t __entries[201] = { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_INDIC_CONJUNCT_BREAK_TABLE_H +#endif // _LIBCPP___CXX03___FORMAT_INDIC_CONJUNCT_BREAK_TABLE_H diff --git a/libcxx/include/__cxx03/__format/parser_std_format_spec.h b/libcxx/include/__cxx03/__format/parser_std_format_spec.h index 1afb5b2c5dd14..394b6e655e726 100644 --- a/libcxx/include/__cxx03/__format/parser_std_format_spec.h +++ b/libcxx/include/__cxx03/__format/parser_std_format_spec.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H -#define _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H +#ifndef _LIBCPP___CXX03___FORMAT_PARSER_STD_FORMAT_SPEC_H +#define _LIBCPP___CXX03___FORMAT_PARSER_STD_FORMAT_SPEC_H /// \file Contains the std-format-spec parser. /// @@ -1169,4 +1169,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FORMAT_PARSER_STD_FORMAT_SPEC_H +#endif // _LIBCPP___CXX03___FORMAT_PARSER_STD_FORMAT_SPEC_H diff --git a/libcxx/include/__cxx03/__format/range_default_formatter.h b/libcxx/include/__cxx03/__format/range_default_formatter.h index c0e07870430e8..ca51a0f0a8227 100644 --- a/libcxx/include/__cxx03/__format/range_default_formatter.h +++ b/libcxx/include/__cxx03/__format/range_default_formatter.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H -#define _LIBCPP___FORMAT_RANGE_DEFAULT_FORMATTER_H +#ifndef _LIBCPP___CXX03___FORMAT_RANGE_DEFAULT_FORMATTER_H +#define _LIBCPP___CXX03___FORMAT_RANGE_DEFAULT_FORMATTER_H #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -211,4 +211,4 @@ struct _LIBCPP_TEMPLATE_VIS formatter<_Rp, _CharT> : __range_default_formatter #include <__cxx03/__bit/countl.h> @@ -599,4 +599,4 @@ class __code_point_view { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_UNICODE_H +#endif // _LIBCPP___CXX03___FORMAT_UNICODE_H diff --git a/libcxx/include/__cxx03/__format/width_estimation_table.h b/libcxx/include/__cxx03/__format/width_estimation_table.h index 2f0367d1c8f98..0929c4bbf0f09 100644 --- a/libcxx/include/__cxx03/__format/width_estimation_table.h +++ b/libcxx/include/__cxx03/__format/width_estimation_table.h @@ -58,8 +58,8 @@ // use or other dealings in these Data Files or Software without prior // written authorization of the copyright holder. -#ifndef _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H -#define _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H +#ifndef _LIBCPP___CXX03___FORMAT_WIDTH_ESTIMATION_TABLE_H +#define _LIBCPP___CXX03___FORMAT_WIDTH_ESTIMATION_TABLE_H #include <__cxx03/__algorithm/ranges_upper_bound.h> #include <__cxx03/__config> @@ -267,4 +267,4 @@ inline constexpr uint32_t __table_upper_bound = 0x0003fffd; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FORMAT_WIDTH_ESTIMATION_TABLE_H +#endif // _LIBCPP___CXX03___FORMAT_WIDTH_ESTIMATION_TABLE_H diff --git a/libcxx/include/__cxx03/__format/write_escaped.h b/libcxx/include/__cxx03/__format/write_escaped.h index 82e65ca988ebf..5711e7c539d02 100644 --- a/libcxx/include/__cxx03/__format/write_escaped.h +++ b/libcxx/include/__cxx03/__format/write_escaped.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FORMAT_WRITE_ESCAPED_H -#define _LIBCPP___FORMAT_WRITE_ESCAPED_H +#ifndef _LIBCPP___CXX03___FORMAT_WRITE_ESCAPED_H +#define _LIBCPP___CXX03___FORMAT_WRITE_ESCAPED_H #include <__cxx03/__algorithm/ranges_copy.h> #include <__cxx03/__algorithm/ranges_for_each.h> @@ -239,4 +239,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FORMAT_WRITE_ESCAPED_H +#endif // _LIBCPP___CXX03___FORMAT_WRITE_ESCAPED_H diff --git a/libcxx/include/__cxx03/__functional/binary_function.h b/libcxx/include/__cxx03/__functional/binary_function.h index 0e54bc5e3c611..cc247eacb8e37 100644 --- a/libcxx/include/__cxx03/__functional/binary_function.h +++ b/libcxx/include/__cxx03/__functional/binary_function.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H -#define _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_BINARY_FUNCTION_H +#define _LIBCPP___CXX03___FUNCTIONAL_BINARY_FUNCTION_H #include <__cxx03/__config> @@ -51,4 +51,4 @@ using __binary_function = __binary_function_keep_layout_base<_Arg1, _Arg2, _Resu _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_BINARY_FUNCTION_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_BINARY_FUNCTION_H diff --git a/libcxx/include/__cxx03/__functional/binary_negate.h b/libcxx/include/__cxx03/__functional/binary_negate.h index 60dfb19918656..e2173d72dc404 100644 --- a/libcxx/include/__cxx03/__functional/binary_negate.h +++ b/libcxx/include/__cxx03/__functional/binary_negate.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H -#define _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_BINARY_NEGATE_H +#define _LIBCPP___CXX03___FUNCTIONAL_BINARY_NEGATE_H #include <__cxx03/__config> #include <__cxx03/__functional/binary_function.h> @@ -48,4 +48,4 @@ not2(const _Predicate& __pred) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_BINARY_NEGATE_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_BINARY_NEGATE_H diff --git a/libcxx/include/__cxx03/__functional/bind.h b/libcxx/include/__cxx03/__functional/bind.h index 5a1a76a6f1f7a..70c4be05ce65e 100644 --- a/libcxx/include/__cxx03/__functional/bind.h +++ b/libcxx/include/__cxx03/__functional/bind.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_BIND_H -#define _LIBCPP___FUNCTIONAL_BIND_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_BIND_H +#define _LIBCPP___CXX03___FUNCTIONAL_BIND_H #include <__cxx03/__config> #include <__cxx03/__functional/invoke.h> @@ -293,4 +293,4 @@ bind(_Fp&& __f, _BoundArgs&&... __bound_args) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_BIND_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_BIND_H diff --git a/libcxx/include/__cxx03/__functional/bind_back.h b/libcxx/include/__cxx03/__functional/bind_back.h index fef99f1852377..2e333b1b14d6a 100644 --- a/libcxx/include/__cxx03/__functional/bind_back.h +++ b/libcxx/include/__cxx03/__functional/bind_back.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_BIND_BACK_H -#define _LIBCPP___FUNCTIONAL_BIND_BACK_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_BIND_BACK_H +#define _LIBCPP___CXX03___FUNCTIONAL_BIND_BACK_H #include <__cxx03/__config> #include <__cxx03/__functional/invoke.h> @@ -80,4 +80,4 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto bind_back(_Fn&& __f, _Args&&... __args) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_BIND_BACK_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_BIND_BACK_H diff --git a/libcxx/include/__cxx03/__functional/bind_front.h b/libcxx/include/__cxx03/__functional/bind_front.h index 1156f53be096e..6447c2d1bc2eb 100644 --- a/libcxx/include/__cxx03/__functional/bind_front.h +++ b/libcxx/include/__cxx03/__functional/bind_front.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_BIND_FRONT_H -#define _LIBCPP___FUNCTIONAL_BIND_FRONT_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_BIND_FRONT_H +#define _LIBCPP___CXX03___FUNCTIONAL_BIND_FRONT_H #include <__cxx03/__config> #include <__cxx03/__functional/invoke.h> @@ -51,4 +51,4 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto bind_front(_Fn&& __f, _Args&&... __args) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_BIND_FRONT_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_BIND_FRONT_H diff --git a/libcxx/include/__cxx03/__functional/binder1st.h b/libcxx/include/__cxx03/__functional/binder1st.h index 1f2f7ebb9c853..21c136ff16d8c 100644 --- a/libcxx/include/__cxx03/__functional/binder1st.h +++ b/libcxx/include/__cxx03/__functional/binder1st.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_BINDER1ST_H -#define _LIBCPP___FUNCTIONAL_BINDER1ST_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_BINDER1ST_H +#define _LIBCPP___CXX03___FUNCTIONAL_BINDER1ST_H #include <__cxx03/__config> #include <__cxx03/__functional/unary_function.h> @@ -51,4 +51,4 @@ bind1st(const _Operation& __op, const _Tp& __x) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_BINDER1ST_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_BINDER1ST_H diff --git a/libcxx/include/__cxx03/__functional/binder2nd.h b/libcxx/include/__cxx03/__functional/binder2nd.h index d70fab8c93b4a..397215b3d9e11 100644 --- a/libcxx/include/__cxx03/__functional/binder2nd.h +++ b/libcxx/include/__cxx03/__functional/binder2nd.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_BINDER2ND_H -#define _LIBCPP___FUNCTIONAL_BINDER2ND_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_BINDER2ND_H +#define _LIBCPP___CXX03___FUNCTIONAL_BINDER2ND_H #include <__cxx03/__config> #include <__cxx03/__functional/unary_function.h> @@ -51,4 +51,4 @@ bind2nd(const _Operation& __op, const _Tp& __x) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_BINDER2ND_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_BINDER2ND_H diff --git a/libcxx/include/__cxx03/__functional/boyer_moore_searcher.h b/libcxx/include/__cxx03/__functional/boyer_moore_searcher.h index e7724ce6f44c0..384c4b53cc270 100644 --- a/libcxx/include/__cxx03/__functional/boyer_moore_searcher.h +++ b/libcxx/include/__cxx03/__functional/boyer_moore_searcher.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H -#define _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_BOYER_MOORE_SEARCHER_H +#define _LIBCPP___CXX03___FUNCTIONAL_BOYER_MOORE_SEARCHER_H #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -303,4 +303,4 @@ _LIBCPP_POP_MACROS #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___FUNCTIONAL_BOYER_MOORE_SEARCHER_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_BOYER_MOORE_SEARCHER_H diff --git a/libcxx/include/__cxx03/__functional/compose.h b/libcxx/include/__cxx03/__functional/compose.h index 504a7e1ca1426..afb6358ad535e 100644 --- a/libcxx/include/__cxx03/__functional/compose.h +++ b/libcxx/include/__cxx03/__functional/compose.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_COMPOSE_H -#define _LIBCPP___FUNCTIONAL_COMPOSE_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_COMPOSE_H +#define _LIBCPP___CXX03___FUNCTIONAL_COMPOSE_H #include <__cxx03/__config> #include <__cxx03/__functional/invoke.h> @@ -50,4 +50,4 @@ _LIBCPP_HIDE_FROM_ABI constexpr auto __compose(_Fn1&& __f1, _Fn2&& __f2) noexcep _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_COMPOSE_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_COMPOSE_H diff --git a/libcxx/include/__cxx03/__functional/default_searcher.h b/libcxx/include/__cxx03/__functional/default_searcher.h index 90ee48fc5e93b..f1ad66990c257 100644 --- a/libcxx/include/__cxx03/__functional/default_searcher.h +++ b/libcxx/include/__cxx03/__functional/default_searcher.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H -#define _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_DEFAULT_SEARCHER_H +#define _LIBCPP___CXX03___FUNCTIONAL_DEFAULT_SEARCHER_H #include <__cxx03/__algorithm/search.h> #include <__cxx03/__config> @@ -51,4 +51,4 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(default_searcher); _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_DEFAULT_SEARCHER_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_DEFAULT_SEARCHER_H diff --git a/libcxx/include/__cxx03/__functional/function.h b/libcxx/include/__cxx03/__functional/function.h index fe3cc8accac63..1d60391494da8 100644 --- a/libcxx/include/__cxx03/__functional/function.h +++ b/libcxx/include/__cxx03/__functional/function.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_FUNCTION_H -#define _LIBCPP___FUNCTIONAL_FUNCTION_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_FUNCTION_H +#define _LIBCPP___CXX03___FUNCTIONAL_FUNCTION_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -1045,4 +1045,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FUNCTIONAL_FUNCTION_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_FUNCTION_H diff --git a/libcxx/include/__cxx03/__functional/hash.h b/libcxx/include/__cxx03/__functional/hash.h index 216d2ae4d1bc5..15473a8572435 100644 --- a/libcxx/include/__cxx03/__functional/hash.h +++ b/libcxx/include/__cxx03/__functional/hash.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_HASH_H -#define _LIBCPP___FUNCTIONAL_HASH_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_HASH_H +#define _LIBCPP___CXX03___FUNCTIONAL_HASH_H #include <__cxx03/__config> #include <__cxx03/__functional/unary_function.h> @@ -539,4 +539,4 @@ using __enable_hash_helper _LIBCPP_NODEBUG = _Type; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_HASH_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_HASH_H diff --git a/libcxx/include/__cxx03/__functional/identity.h b/libcxx/include/__cxx03/__functional/identity.h index 7d016af84f854..61e5ebdb31e6e 100644 --- a/libcxx/include/__cxx03/__functional/identity.h +++ b/libcxx/include/__cxx03/__functional/identity.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_IDENTITY_H -#define _LIBCPP___FUNCTIONAL_IDENTITY_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_IDENTITY_H +#define _LIBCPP___CXX03___FUNCTIONAL_IDENTITY_H #include <__cxx03/__config> #include <__cxx03/__fwd/functional.h> @@ -62,4 +62,4 @@ struct __is_identity > : true_type {}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_IDENTITY_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_IDENTITY_H diff --git a/libcxx/include/__cxx03/__functional/invoke.h b/libcxx/include/__cxx03/__functional/invoke.h index a9c039bc0379b..d17a2d58e471f 100644 --- a/libcxx/include/__cxx03/__functional/invoke.h +++ b/libcxx/include/__cxx03/__functional/invoke.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_INVOKE_H -#define _LIBCPP___FUNCTIONAL_INVOKE_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_INVOKE_H +#define _LIBCPP___CXX03___FUNCTIONAL_INVOKE_H #include <__cxx03/__config> #include <__cxx03/__type_traits/invoke.h> @@ -51,4 +51,4 @@ invoke_r(_Fn&& __f, _Args&&... __args) noexcept(is_nothrow_invocable_r_v<_Result _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_INVOKE_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_INVOKE_H diff --git a/libcxx/include/__cxx03/__functional/is_transparent.h b/libcxx/include/__cxx03/__functional/is_transparent.h index de978871404b8..b630aca633672 100644 --- a/libcxx/include/__cxx03/__functional/is_transparent.h +++ b/libcxx/include/__cxx03/__functional/is_transparent.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_IS_TRANSPARENT -#define _LIBCPP___FUNCTIONAL_IS_TRANSPARENT +#ifndef _LIBCPP___CXX03___FUNCTIONAL_IS_TRANSPARENT +#define _LIBCPP___CXX03___FUNCTIONAL_IS_TRANSPARENT #include <__cxx03/__config> #include <__cxx03/__type_traits/void_t.h> @@ -31,4 +31,4 @@ inline const bool __is_transparent_v<_Tp, _Up, __void_t #include <__cxx03/__functional/binary_function.h> @@ -51,4 +51,4 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 __mem_fn<_Rp _Tp::*> _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_MEM_FN_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_MEM_FN_H diff --git a/libcxx/include/__cxx03/__functional/mem_fun_ref.h b/libcxx/include/__cxx03/__functional/mem_fun_ref.h index e0e2f29b95d16..ef962231dc92b 100644 --- a/libcxx/include/__cxx03/__functional/mem_fun_ref.h +++ b/libcxx/include/__cxx03/__functional/mem_fun_ref.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H -#define _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_MEM_FUN_REF_H +#define _LIBCPP___CXX03___FUNCTIONAL_MEM_FUN_REF_H #include <__cxx03/__config> #include <__cxx03/__functional/binary_function.h> @@ -143,4 +143,4 @@ mem_fun_ref(_Sp (_Tp::*__f)(_Ap) const) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_MEM_FUN_REF_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_MEM_FUN_REF_H diff --git a/libcxx/include/__cxx03/__functional/not_fn.h b/libcxx/include/__cxx03/__functional/not_fn.h index 8b9264af64c58..a6c648bc0beb2 100644 --- a/libcxx/include/__cxx03/__functional/not_fn.h +++ b/libcxx/include/__cxx03/__functional/not_fn.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_NOT_FN_H -#define _LIBCPP___FUNCTIONAL_NOT_FN_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_NOT_FN_H +#define _LIBCPP___CXX03___FUNCTIONAL_NOT_FN_H #include <__cxx03/__config> #include <__cxx03/__functional/invoke.h> @@ -50,4 +50,4 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 auto not_fn(_Fn&& __f) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_NOT_FN_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_NOT_FN_H diff --git a/libcxx/include/__cxx03/__functional/operations.h b/libcxx/include/__cxx03/__functional/operations.h index c05579e35e835..ddbe71bdc8b68 100644 --- a/libcxx/include/__cxx03/__functional/operations.h +++ b/libcxx/include/__cxx03/__functional/operations.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_OPERATIONS_H -#define _LIBCPP___FUNCTIONAL_OPERATIONS_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_OPERATIONS_H +#define _LIBCPP___CXX03___FUNCTIONAL_OPERATIONS_H #include <__cxx03/__config> #include <__cxx03/__functional/binary_function.h> @@ -538,4 +538,4 @@ struct _LIBCPP_TEMPLATE_VIS logical_or { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_OPERATIONS_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_OPERATIONS_H diff --git a/libcxx/include/__cxx03/__functional/perfect_forward.h b/libcxx/include/__cxx03/__functional/perfect_forward.h index 45ecb68250dc9..230e0dc21b429 100644 --- a/libcxx/include/__cxx03/__functional/perfect_forward.h +++ b/libcxx/include/__cxx03/__functional/perfect_forward.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H -#define _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_PERFECT_FORWARD_H +#define _LIBCPP___CXX03___FUNCTIONAL_PERFECT_FORWARD_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -101,4 +101,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FUNCTIONAL_PERFECT_FORWARD_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_PERFECT_FORWARD_H diff --git a/libcxx/include/__cxx03/__functional/pointer_to_binary_function.h b/libcxx/include/__cxx03/__functional/pointer_to_binary_function.h index d033f9050f0c3..72474255d7fe2 100644 --- a/libcxx/include/__cxx03/__functional/pointer_to_binary_function.h +++ b/libcxx/include/__cxx03/__functional/pointer_to_binary_function.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H -#define _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H +#define _LIBCPP___CXX03___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H #include <__cxx03/__config> #include <__cxx03/__functional/binary_function.h> @@ -41,4 +41,4 @@ ptr_fun(_Result (*__f)(_Arg1, _Arg2)) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_POINTER_TO_BINARY_FUNCTION_H diff --git a/libcxx/include/__cxx03/__functional/pointer_to_unary_function.h b/libcxx/include/__cxx03/__functional/pointer_to_unary_function.h index 9e7f62915c91f..8540ad07f3ec0 100644 --- a/libcxx/include/__cxx03/__functional/pointer_to_unary_function.h +++ b/libcxx/include/__cxx03/__functional/pointer_to_unary_function.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H -#define _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H +#define _LIBCPP___CXX03___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H #include <__cxx03/__config> #include <__cxx03/__functional/unary_function.h> @@ -41,4 +41,4 @@ ptr_fun(_Result (*__f)(_Arg)) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_POINTER_TO_UNARY_FUNCTION_H diff --git a/libcxx/include/__cxx03/__functional/ranges_operations.h b/libcxx/include/__cxx03/__functional/ranges_operations.h index e8a2b367c9350..e48593824852d 100644 --- a/libcxx/include/__cxx03/__functional/ranges_operations.h +++ b/libcxx/include/__cxx03/__functional/ranges_operations.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H -#define _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_RANGES_OPERATIONS_H +#define _LIBCPP___CXX03___FUNCTIONAL_RANGES_OPERATIONS_H #include <__cxx03/__concepts/equality_comparable.h> #include <__cxx03/__concepts/totally_ordered.h> @@ -106,4 +106,4 @@ inline const bool __desugars_to_v<__less_tag, ranges::less, _Tp, _Up> = true; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_RANGES_OPERATIONS_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_RANGES_OPERATIONS_H diff --git a/libcxx/include/__cxx03/__functional/reference_wrapper.h b/libcxx/include/__cxx03/__functional/reference_wrapper.h index 73788e1fdb89b..e217bdf543351 100644 --- a/libcxx/include/__cxx03/__functional/reference_wrapper.h +++ b/libcxx/include/__cxx03/__functional/reference_wrapper.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H -#define _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_REFERENCE_WRAPPER_H +#define _LIBCPP___CXX03___FUNCTIONAL_REFERENCE_WRAPPER_H #include <__cxx03/__compare/synth_three_way.h> #include <__cxx03/__concepts/boolean_testable.h> @@ -151,4 +151,4 @@ void cref(const _Tp&&) = delete; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_REFERENCE_WRAPPER_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_REFERENCE_WRAPPER_H diff --git a/libcxx/include/__cxx03/__functional/unary_function.h b/libcxx/include/__cxx03/__functional/unary_function.h index 9b1e336f15fa4..45ba29ee2cac5 100644 --- a/libcxx/include/__cxx03/__functional/unary_function.h +++ b/libcxx/include/__cxx03/__functional/unary_function.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H -#define _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_UNARY_FUNCTION_H +#define _LIBCPP___CXX03___FUNCTIONAL_UNARY_FUNCTION_H #include <__cxx03/__config> @@ -48,4 +48,4 @@ using __unary_function = __unary_function_keep_layout_base<_Arg, _Result>; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_UNARY_FUNCTION_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_UNARY_FUNCTION_H diff --git a/libcxx/include/__cxx03/__functional/unary_negate.h b/libcxx/include/__cxx03/__functional/unary_negate.h index 7154d234b007f..4d527865f378c 100644 --- a/libcxx/include/__cxx03/__functional/unary_negate.h +++ b/libcxx/include/__cxx03/__functional/unary_negate.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H -#define _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_UNARY_NEGATE_H +#define _LIBCPP___CXX03___FUNCTIONAL_UNARY_NEGATE_H #include <__cxx03/__config> #include <__cxx03/__functional/unary_function.h> @@ -45,4 +45,4 @@ not1(const _Predicate& __pred) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_UNARY_NEGATE_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_UNARY_NEGATE_H diff --git a/libcxx/include/__cxx03/__functional/weak_result_type.h b/libcxx/include/__cxx03/__functional/weak_result_type.h index e1d62d634ca33..539989dda2d97 100644 --- a/libcxx/include/__cxx03/__functional/weak_result_type.h +++ b/libcxx/include/__cxx03/__functional/weak_result_type.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H -#define _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_WEAK_RESULT_TYPE_H +#define _LIBCPP___CXX03___FUNCTIONAL_WEAK_RESULT_TYPE_H #include <__cxx03/__config> #include <__cxx03/__functional/binary_function.h> @@ -228,4 +228,4 @@ struct __invoke_return { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_WEAK_RESULT_TYPE_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_WEAK_RESULT_TYPE_H diff --git a/libcxx/include/__cxx03/__fwd/array.h b/libcxx/include/__cxx03/__fwd/array.h index 36343371a2278..f2648a1986e27 100644 --- a/libcxx/include/__cxx03/__fwd/array.h +++ b/libcxx/include/__cxx03/__fwd/array.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_ARRAY_H -#define _LIBCPP___FWD_ARRAY_H +#ifndef _LIBCPP___CXX03___FWD_ARRAY_H +#define _LIBCPP___CXX03___FWD_ARRAY_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -43,4 +43,4 @@ struct __is_std_array > : true_type {}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_ARRAY_H +#endif // _LIBCPP___CXX03___FWD_ARRAY_H diff --git a/libcxx/include/__cxx03/__fwd/bit_reference.h b/libcxx/include/__cxx03/__fwd/bit_reference.h index 6bda18429c392..e04a47ff97a61 100644 --- a/libcxx/include/__cxx03/__fwd/bit_reference.h +++ b/libcxx/include/__cxx03/__fwd/bit_reference.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_BIT_REFERENCE_H -#define _LIBCPP___FWD_BIT_REFERENCE_H +#ifndef _LIBCPP___CXX03___FWD_BIT_REFERENCE_H +#define _LIBCPP___CXX03___FWD_BIT_REFERENCE_H #include <__cxx03/__config> @@ -22,4 +22,4 @@ class __bit_iterator; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_BIT_REFERENCE_H +#endif // _LIBCPP___CXX03___FWD_BIT_REFERENCE_H diff --git a/libcxx/include/__cxx03/__fwd/complex.h b/libcxx/include/__cxx03/__fwd/complex.h index e734f2db76fed..bb1ae20ab3bf8 100644 --- a/libcxx/include/__cxx03/__fwd/complex.h +++ b/libcxx/include/__cxx03/__fwd/complex.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_COMPLEX_H -#define _LIBCPP___FWD_COMPLEX_H +#ifndef _LIBCPP___CXX03___FWD_COMPLEX_H +#define _LIBCPP___CXX03___FWD_COMPLEX_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -39,4 +39,4 @@ _LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& get(const complex<_Tp>&&) noexcept; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_COMPLEX_H +#endif // _LIBCPP___CXX03___FWD_COMPLEX_H diff --git a/libcxx/include/__cxx03/__fwd/deque.h b/libcxx/include/__cxx03/__fwd/deque.h index 31aa8c3799823..7d1c6f79d0d77 100644 --- a/libcxx/include/__cxx03/__fwd/deque.h +++ b/libcxx/include/__cxx03/__fwd/deque.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_DEQUE_H -#define _LIBCPP___FWD_DEQUE_H +#ifndef _LIBCPP___CXX03___FWD_DEQUE_H +#define _LIBCPP___CXX03___FWD_DEQUE_H #include <__cxx03/__config> #include <__cxx03/__fwd/memory.h> @@ -23,4 +23,4 @@ class _LIBCPP_TEMPLATE_VIS deque; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_DEQUE_H +#endif // _LIBCPP___CXX03___FWD_DEQUE_H diff --git a/libcxx/include/__cxx03/__fwd/format.h b/libcxx/include/__cxx03/__fwd/format.h index 2777433363270..3da3fd728266b 100644 --- a/libcxx/include/__cxx03/__fwd/format.h +++ b/libcxx/include/__cxx03/__fwd/format.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_FORMAT_H -#define _LIBCPP___FWD_FORMAT_H +#ifndef _LIBCPP___CXX03___FWD_FORMAT_H +#define _LIBCPP___CXX03___FWD_FORMAT_H #include <__cxx03/__config> #include <__cxx03/__iterator/concepts.h> @@ -35,4 +35,4 @@ struct _LIBCPP_TEMPLATE_VIS formatter; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_FORMAT_H +#endif // _LIBCPP___CXX03___FWD_FORMAT_H diff --git a/libcxx/include/__cxx03/__fwd/fstream.h b/libcxx/include/__cxx03/__fwd/fstream.h index 717cb8c583d2c..8cc5d2b9efd4e 100644 --- a/libcxx/include/__cxx03/__fwd/fstream.h +++ b/libcxx/include/__cxx03/__fwd/fstream.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_FSTREAM_H -#define _LIBCPP___FWD_FSTREAM_H +#ifndef _LIBCPP___CXX03___FWD_FSTREAM_H +#define _LIBCPP___CXX03___FWD_FSTREAM_H #include <__cxx03/__config> #include <__cxx03/__fwd/string.h> @@ -50,4 +50,4 @@ class _LIBCPP_PREFERRED_NAME(fstream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERR _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_FSTREAM_H +#endif // _LIBCPP___CXX03___FWD_FSTREAM_H diff --git a/libcxx/include/__cxx03/__fwd/functional.h b/libcxx/include/__cxx03/__fwd/functional.h index e19b802d178ca..924874ca70050 100644 --- a/libcxx/include/__cxx03/__fwd/functional.h +++ b/libcxx/include/__cxx03/__fwd/functional.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_FUNCTIONAL_H -#define _LIBCPP___FWD_FUNCTIONAL_H +#ifndef _LIBCPP___CXX03___FWD_FUNCTIONAL_H +#define _LIBCPP___CXX03___FWD_FUNCTIONAL_H #include <__cxx03/__config> @@ -25,4 +25,4 @@ class _LIBCPP_TEMPLATE_VIS reference_wrapper; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_FUNCTIONAL_H +#endif // _LIBCPP___CXX03___FWD_FUNCTIONAL_H diff --git a/libcxx/include/__cxx03/__fwd/ios.h b/libcxx/include/__cxx03/__fwd/ios.h index f5ba74c9067bb..dc03e8c6bab2f 100644 --- a/libcxx/include/__cxx03/__fwd/ios.h +++ b/libcxx/include/__cxx03/__fwd/ios.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_IOS_H -#define _LIBCPP___FWD_IOS_H +#ifndef _LIBCPP___CXX03___FWD_IOS_H +#define _LIBCPP___CXX03___FWD_IOS_H #include <__cxx03/__config> #include <__cxx03/__fwd/string.h> @@ -40,4 +40,4 @@ using streamoff = long long; // for char_traits in _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_IOS_H +#endif // _LIBCPP___CXX03___FWD_IOS_H diff --git a/libcxx/include/__cxx03/__fwd/istream.h b/libcxx/include/__cxx03/__fwd/istream.h index 8975ac26baf6b..f3edc7859c642 100644 --- a/libcxx/include/__cxx03/__fwd/istream.h +++ b/libcxx/include/__cxx03/__fwd/istream.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_ISTREAM_H -#define _LIBCPP___FWD_ISTREAM_H +#ifndef _LIBCPP___CXX03___FWD_ISTREAM_H +#define _LIBCPP___CXX03___FWD_ISTREAM_H #include <__cxx03/__config> #include <__cxx03/__fwd/string.h> @@ -40,4 +40,4 @@ class _LIBCPP_PREFERRED_NAME(iostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFER _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_ISTREAM_H +#endif // _LIBCPP___CXX03___FWD_ISTREAM_H diff --git a/libcxx/include/__cxx03/__fwd/mdspan.h b/libcxx/include/__cxx03/__fwd/mdspan.h index 369da43a20296..50209798a1443 100644 --- a/libcxx/include/__cxx03/__fwd/mdspan.h +++ b/libcxx/include/__cxx03/__fwd/mdspan.h @@ -14,8 +14,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___MDSPAN_LAYOUTS_H -#define _LIBCPP___MDSPAN_LAYOUTS_H +#ifndef _LIBCPP___CXX03___MDSPAN_LAYOUTS_H +#define _LIBCPP___CXX03___MDSPAN_LAYOUTS_H #include <__cxx03/__config> @@ -54,4 +54,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MDSPAN_LAYOUTS_H +#endif // _LIBCPP___CXX03___MDSPAN_LAYOUTS_H diff --git a/libcxx/include/__cxx03/__fwd/memory.h b/libcxx/include/__cxx03/__fwd/memory.h index 109c0f6c051cc..df76b1747c20a 100644 --- a/libcxx/include/__cxx03/__fwd/memory.h +++ b/libcxx/include/__cxx03/__fwd/memory.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_MEMORY_H -#define _LIBCPP___FWD_MEMORY_H +#ifndef _LIBCPP___CXX03___FWD_MEMORY_H +#define _LIBCPP___CXX03___FWD_MEMORY_H #include <__cxx03/__config> @@ -22,4 +22,4 @@ class _LIBCPP_TEMPLATE_VIS allocator; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_MEMORY_H +#endif // _LIBCPP___CXX03___FWD_MEMORY_H diff --git a/libcxx/include/__cxx03/__fwd/memory_resource.h b/libcxx/include/__cxx03/__fwd/memory_resource.h index 1a12dcfdaf627..aefa00a12a835 100644 --- a/libcxx/include/__cxx03/__fwd/memory_resource.h +++ b/libcxx/include/__cxx03/__fwd/memory_resource.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_MEMORY_RESOURCE_H -#define _LIBCPP___FWD_MEMORY_RESOURCE_H +#ifndef _LIBCPP___CXX03___FWD_MEMORY_RESOURCE_H +#define _LIBCPP___CXX03___FWD_MEMORY_RESOURCE_H #include <__cxx03/__config> @@ -24,4 +24,4 @@ class _LIBCPP_AVAILABILITY_PMR _LIBCPP_TEMPLATE_VIS polymorphic_allocator; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_MEMORY_RESOURCE_H +#endif // _LIBCPP___CXX03___FWD_MEMORY_RESOURCE_H diff --git a/libcxx/include/__cxx03/__fwd/ostream.h b/libcxx/include/__cxx03/__fwd/ostream.h index 5660ac50aac46..b5061e6d3bc6d 100644 --- a/libcxx/include/__cxx03/__fwd/ostream.h +++ b/libcxx/include/__cxx03/__fwd/ostream.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_OSTREAM_H -#define _LIBCPP___FWD_OSTREAM_H +#ifndef _LIBCPP___CXX03___FWD_OSTREAM_H +#define _LIBCPP___CXX03___FWD_OSTREAM_H #include <__cxx03/__config> #include <__cxx03/__fwd/string.h> @@ -32,4 +32,4 @@ class _LIBCPP_PREFERRED_NAME(ostream) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFERR _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_OSTREAM_H +#endif // _LIBCPP___CXX03___FWD_OSTREAM_H diff --git a/libcxx/include/__cxx03/__fwd/pair.h b/libcxx/include/__cxx03/__fwd/pair.h index 36656b454e0ab..092374b509606 100644 --- a/libcxx/include/__cxx03/__fwd/pair.h +++ b/libcxx/include/__cxx03/__fwd/pair.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_PAIR_H -#define _LIBCPP___FWD_PAIR_H +#ifndef _LIBCPP___CXX03___FWD_PAIR_H +#define _LIBCPP___CXX03___FWD_PAIR_H #include <__cxx03/__config> #include <__cxx03/__fwd/tuple.h> @@ -42,4 +42,4 @@ get(const pair<_T1, _T2>&&) _NOEXCEPT; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_PAIR_H +#endif // _LIBCPP___CXX03___FWD_PAIR_H diff --git a/libcxx/include/__cxx03/__fwd/queue.h b/libcxx/include/__cxx03/__fwd/queue.h index 54afd5113ba89..c2f68089d0e33 100644 --- a/libcxx/include/__cxx03/__fwd/queue.h +++ b/libcxx/include/__cxx03/__fwd/queue.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_QUEUE_H -#define _LIBCPP___FWD_QUEUE_H +#ifndef _LIBCPP___CXX03___FWD_QUEUE_H +#define _LIBCPP___CXX03___FWD_QUEUE_H #include <__cxx03/__config> #include <__cxx03/__functional/operations.h> @@ -28,4 +28,4 @@ class _LIBCPP_TEMPLATE_VIS priority_queue; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_QUEUE_H +#endif // _LIBCPP___CXX03___FWD_QUEUE_H diff --git a/libcxx/include/__cxx03/__fwd/span.h b/libcxx/include/__cxx03/__fwd/span.h index 47ed3eca5af4e..415a3c5ba8a55 100644 --- a/libcxx/include/__cxx03/__fwd/span.h +++ b/libcxx/include/__cxx03/__fwd/span.h @@ -7,8 +7,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_SPAN_H -#define _LIBCPP___FWD_SPAN_H +#ifndef _LIBCPP___CXX03___FWD_SPAN_H +#define _LIBCPP___CXX03___FWD_SPAN_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -35,4 +35,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___FWD_SPAN_H +#endif // _LIBCPP___CXX03___FWD_SPAN_H diff --git a/libcxx/include/__cxx03/__fwd/sstream.h b/libcxx/include/__cxx03/__fwd/sstream.h index cbb53942c8212..32ae42cd7b020 100644 --- a/libcxx/include/__cxx03/__fwd/sstream.h +++ b/libcxx/include/__cxx03/__fwd/sstream.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_SSTREAM_H -#define _LIBCPP___FWD_SSTREAM_H +#ifndef _LIBCPP___CXX03___FWD_SSTREAM_H +#define _LIBCPP___CXX03___FWD_SSTREAM_H #include <__cxx03/__config> #include <__cxx03/__fwd/memory.h> @@ -55,4 +55,4 @@ class _LIBCPP_PREFERRED_NAME(stringstream) _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_SSTREAM_H +#endif // _LIBCPP___CXX03___FWD_SSTREAM_H diff --git a/libcxx/include/__cxx03/__fwd/stack.h b/libcxx/include/__cxx03/__fwd/stack.h index ddd7a67615876..715356e91b411 100644 --- a/libcxx/include/__cxx03/__fwd/stack.h +++ b/libcxx/include/__cxx03/__fwd/stack.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_STACK_H -#define _LIBCPP___FWD_STACK_H +#ifndef _LIBCPP___CXX03___FWD_STACK_H +#define _LIBCPP___CXX03___FWD_STACK_H #include <__cxx03/__config> #include <__cxx03/__fwd/deque.h> @@ -23,4 +23,4 @@ class _LIBCPP_TEMPLATE_VIS stack; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_STACK_H +#endif // _LIBCPP___CXX03___FWD_STACK_H diff --git a/libcxx/include/__cxx03/__fwd/streambuf.h b/libcxx/include/__cxx03/__fwd/streambuf.h index 0b448836aaef7..d22be50ce8ad1 100644 --- a/libcxx/include/__cxx03/__fwd/streambuf.h +++ b/libcxx/include/__cxx03/__fwd/streambuf.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_STREAMBUF_H -#define _LIBCPP___FWD_STREAMBUF_H +#ifndef _LIBCPP___CXX03___FWD_STREAMBUF_H +#define _LIBCPP___CXX03___FWD_STREAMBUF_H #include <__cxx03/__config> #include <__cxx03/__fwd/string.h> @@ -32,4 +32,4 @@ class _LIBCPP_PREFERRED_NAME(streambuf) _LIBCPP_IF_WIDE_CHARACTERS(_LIBCPP_PREFE _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_STREAMBUF_H +#endif // _LIBCPP___CXX03___FWD_STREAMBUF_H diff --git a/libcxx/include/__cxx03/__fwd/string.h b/libcxx/include/__cxx03/__fwd/string.h index 07042b205e8ce..21c2584c6e95b 100644 --- a/libcxx/include/__cxx03/__fwd/string.h +++ b/libcxx/include/__cxx03/__fwd/string.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_STRING_H -#define _LIBCPP___FWD_STRING_H +#ifndef _LIBCPP___CXX03___FWD_STRING_H +#define _LIBCPP___CXX03___FWD_STRING_H #include <__cxx03/__config> #include <__cxx03/__fwd/memory.h> @@ -104,4 +104,4 @@ class _LIBCPP_PREFERRED_NAME(string) _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_STRING_H +#endif // _LIBCPP___CXX03___FWD_STRING_H diff --git a/libcxx/include/__cxx03/__fwd/string_view.h b/libcxx/include/__cxx03/__fwd/string_view.h index 25ee230d20b33..76c608b46b1c6 100644 --- a/libcxx/include/__cxx03/__fwd/string_view.h +++ b/libcxx/include/__cxx03/__fwd/string_view.h @@ -7,8 +7,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_STRING_VIEW_H -#define _LIBCPP___FWD_STRING_VIEW_H +#ifndef _LIBCPP___CXX03___FWD_STRING_VIEW_H +#define _LIBCPP___CXX03___FWD_STRING_VIEW_H #include <__cxx03/__config> #include <__cxx03/__fwd/string.h> @@ -47,4 +47,4 @@ class _LIBCPP_PREFERRED_NAME(string_view) // clang-format on _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_STRING_VIEW_H +#endif // _LIBCPP___CXX03___FWD_STRING_VIEW_H diff --git a/libcxx/include/__cxx03/__fwd/subrange.h b/libcxx/include/__cxx03/__fwd/subrange.h index aebbd866daeb2..34ba3504d0499 100644 --- a/libcxx/include/__cxx03/__fwd/subrange.h +++ b/libcxx/include/__cxx03/__fwd/subrange.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_SUBRANGE_H -#define _LIBCPP___FWD_SUBRANGE_H +#ifndef _LIBCPP___CXX03___FWD_SUBRANGE_H +#define _LIBCPP___CXX03___FWD_SUBRANGE_H #include <__cxx03/__concepts/copyable.h> #include <__cxx03/__config> @@ -46,4 +46,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___FWD_SUBRANGE_H +#endif // _LIBCPP___CXX03___FWD_SUBRANGE_H diff --git a/libcxx/include/__cxx03/__fwd/tuple.h b/libcxx/include/__cxx03/__fwd/tuple.h index 75f7e6d16aecf..fed99583f199f 100644 --- a/libcxx/include/__cxx03/__fwd/tuple.h +++ b/libcxx/include/__cxx03/__fwd/tuple.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_TUPLE_H -#define _LIBCPP___FWD_TUPLE_H +#ifndef _LIBCPP___CXX03___FWD_TUPLE_H +#define _LIBCPP___CXX03___FWD_TUPLE_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -49,4 +49,4 @@ get(const tuple<_Tp...>&&) _NOEXCEPT; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_TUPLE_H +#endif // _LIBCPP___CXX03___FWD_TUPLE_H diff --git a/libcxx/include/__cxx03/__fwd/vector.h b/libcxx/include/__cxx03/__fwd/vector.h index 3ed34e9f9ef94..4133173d765c4 100644 --- a/libcxx/include/__cxx03/__fwd/vector.h +++ b/libcxx/include/__cxx03/__fwd/vector.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___FWD_VECTOR_H -#define _LIBCPP___FWD_VECTOR_H +#ifndef _LIBCPP___CXX03___FWD_VECTOR_H +#define _LIBCPP___CXX03___FWD_VECTOR_H #include <__cxx03/__config> #include <__cxx03/__fwd/memory.h> @@ -23,4 +23,4 @@ class _LIBCPP_TEMPLATE_VIS vector; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FWD_VECTOR_H +#endif // _LIBCPP___CXX03___FWD_VECTOR_H diff --git a/libcxx/include/__cxx03/__hash_table b/libcxx/include/__cxx03/__hash_table index 348dcaf01e8c1..4a27681442c27 100644 --- a/libcxx/include/__cxx03/__hash_table +++ b/libcxx/include/__cxx03/__hash_table @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___HASH_TABLE -#define _LIBCPP___HASH_TABLE +#ifndef _LIBCPP___CXX03___HASH_TABLE +#define _LIBCPP___CXX03___HASH_TABLE #include <__cxx03/__algorithm/max.h> #include <__cxx03/__algorithm/min.h> @@ -2041,4 +2041,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___HASH_TABLE +#endif // _LIBCPP___CXX03___HASH_TABLE diff --git a/libcxx/include/__cxx03/__ios/fpos.h b/libcxx/include/__cxx03/__ios/fpos.h index 20904d3f5469d..5f16bfd4caec9 100644 --- a/libcxx/include/__cxx03/__ios/fpos.h +++ b/libcxx/include/__cxx03/__ios/fpos.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___IOS_FPOS_H -#define _LIBCPP___IOS_FPOS_H +#ifndef _LIBCPP___CXX03___IOS_FPOS_H +#define _LIBCPP___CXX03___IOS_FPOS_H #include <__cxx03/__config> #include <__cxx03/__fwd/ios.h> @@ -73,4 +73,4 @@ inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const fpos<_StateT>& __x, const fpo _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___IOS_FPOS_H +#endif // _LIBCPP___CXX03___IOS_FPOS_H diff --git a/libcxx/include/__cxx03/__iterator/access.h b/libcxx/include/__cxx03/__iterator/access.h index 2d7b4d16d47ce..2d61d4a879d4f 100644 --- a/libcxx/include/__cxx03/__iterator/access.h +++ b/libcxx/include/__cxx03/__iterator/access.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_ACCESS_H -#define _LIBCPP___ITERATOR_ACCESS_H +#ifndef _LIBCPP___CXX03___ITERATOR_ACCESS_H +#define _LIBCPP___CXX03___ITERATOR_ACCESS_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -92,4 +92,4 @@ _LIBCPP_HIDE_FROM_ABI typename _Cp::const_iterator end(const _Cp& __c) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_ACCESS_H +#endif // _LIBCPP___CXX03___ITERATOR_ACCESS_H diff --git a/libcxx/include/__cxx03/__iterator/advance.h b/libcxx/include/__cxx03/__iterator/advance.h index b481652fbed9d..ac4904829b7ee 100644 --- a/libcxx/include/__cxx03/__iterator/advance.h +++ b/libcxx/include/__cxx03/__iterator/advance.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_ADVANCE_H -#define _LIBCPP___ITERATOR_ADVANCE_H +#ifndef _LIBCPP___CXX03___ITERATOR_ADVANCE_H +#define _LIBCPP___CXX03___ITERATOR_ADVANCE_H #include <__cxx03/__assert> #include <__cxx03/__concepts/assignable.h> @@ -202,4 +202,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_ADVANCE_H +#endif // _LIBCPP___CXX03___ITERATOR_ADVANCE_H diff --git a/libcxx/include/__cxx03/__iterator/aliasing_iterator.h b/libcxx/include/__cxx03/__iterator/aliasing_iterator.h index a3cb555606cb9..93da1d28ef094 100644 --- a/libcxx/include/__cxx03/__iterator/aliasing_iterator.h +++ b/libcxx/include/__cxx03/__iterator/aliasing_iterator.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_ALIASING_ITERATOR_H -#define _LIBCPP___ITERATOR_ALIASING_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_ALIASING_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_ALIASING_ITERATOR_H #include <__cxx03/__config> #include <__cxx03/__iterator/iterator_traits.h> @@ -124,4 +124,4 @@ using __aliasing_iterator = typename __aliasing_iterator_wrapper<_BaseT, _Alias> _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_ALIASING_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_ALIASING_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/back_insert_iterator.h b/libcxx/include/__cxx03/__iterator/back_insert_iterator.h index 2d3885951d134..962639a2746bf 100644 --- a/libcxx/include/__cxx03/__iterator/back_insert_iterator.h +++ b/libcxx/include/__cxx03/__iterator/back_insert_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H -#define _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_BACK_INSERT_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_BACK_INSERT_ITERATOR_H #include <__cxx03/__config> #include <__cxx03/__iterator/iterator.h> @@ -82,4 +82,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_BACK_INSERT_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_BACK_INSERT_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/bounded_iter.h b/libcxx/include/__cxx03/__iterator/bounded_iter.h index dc93be089b1b8..d361e74283de7 100644 --- a/libcxx/include/__cxx03/__iterator/bounded_iter.h +++ b/libcxx/include/__cxx03/__iterator/bounded_iter.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_BOUNDED_ITER_H -#define _LIBCPP___ITERATOR_BOUNDED_ITER_H +#ifndef _LIBCPP___CXX03___ITERATOR_BOUNDED_ITER_H +#define _LIBCPP___CXX03___ITERATOR_BOUNDED_ITER_H #include <__cxx03/__assert> #include <__cxx03/__compare/ordering.h> @@ -280,4 +280,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_BOUNDED_ITER_H +#endif // _LIBCPP___CXX03___ITERATOR_BOUNDED_ITER_H diff --git a/libcxx/include/__cxx03/__iterator/common_iterator.h b/libcxx/include/__cxx03/__iterator/common_iterator.h index 5d052c0d2300e..6083a23e67a86 100644 --- a/libcxx/include/__cxx03/__iterator/common_iterator.h +++ b/libcxx/include/__cxx03/__iterator/common_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_COMMON_ITERATOR_H -#define _LIBCPP___ITERATOR_COMMON_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_COMMON_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_COMMON_ITERATOR_H #include <__cxx03/__assert> #include <__cxx03/__concepts/assignable.h> @@ -296,4 +296,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_COMMON_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_COMMON_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/concepts.h b/libcxx/include/__cxx03/__iterator/concepts.h index 4973ce8987ef5..af7d0c9a0541d 100644 --- a/libcxx/include/__cxx03/__iterator/concepts.h +++ b/libcxx/include/__cxx03/__iterator/concepts.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_CONCEPTS_H -#define _LIBCPP___ITERATOR_CONCEPTS_H +#ifndef _LIBCPP___CXX03___ITERATOR_CONCEPTS_H +#define _LIBCPP___CXX03___ITERATOR_CONCEPTS_H #include <__cxx03/__concepts/arithmetic.h> #include <__cxx03/__concepts/assignable.h> @@ -254,4 +254,4 @@ using __has_random_access_iterator_category_or_concept _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_CONCEPTS_H +#endif // _LIBCPP___CXX03___ITERATOR_CONCEPTS_H diff --git a/libcxx/include/__cxx03/__iterator/counted_iterator.h b/libcxx/include/__cxx03/__iterator/counted_iterator.h index 161ec54a1a3b1..9d6004dc90b84 100644 --- a/libcxx/include/__cxx03/__iterator/counted_iterator.h +++ b/libcxx/include/__cxx03/__iterator/counted_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_COUNTED_ITERATOR_H -#define _LIBCPP___ITERATOR_COUNTED_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_COUNTED_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_COUNTED_ITERATOR_H #include <__cxx03/__assert> #include <__cxx03/__concepts/assignable.h> @@ -286,4 +286,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_COUNTED_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_COUNTED_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/cpp17_iterator_concepts.h b/libcxx/include/__cxx03/__iterator/cpp17_iterator_concepts.h index 938884e5f69ab..aed3527aee08a 100644 --- a/libcxx/include/__cxx03/__iterator/cpp17_iterator_concepts.h +++ b/libcxx/include/__cxx03/__iterator/cpp17_iterator_concepts.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H -#define _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H +#ifndef _LIBCPP___CXX03___ITERATOR_CPP17_ITERATOR_CONCEPTS_H +#define _LIBCPP___CXX03___ITERATOR_CPP17_ITERATOR_CONCEPTS_H #include <__cxx03/__concepts/boolean_testable.h> #include <__cxx03/__concepts/convertible_to.h> @@ -187,4 +187,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_CPP17_ITERATOR_CONCEPTS_H +#endif // _LIBCPP___CXX03___ITERATOR_CPP17_ITERATOR_CONCEPTS_H diff --git a/libcxx/include/__cxx03/__iterator/data.h b/libcxx/include/__cxx03/__iterator/data.h index d4f26608d9c49..58047e4b6c755 100644 --- a/libcxx/include/__cxx03/__iterator/data.h +++ b/libcxx/include/__cxx03/__iterator/data.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_DATA_H -#define _LIBCPP___ITERATOR_DATA_H +#ifndef _LIBCPP___CXX03___ITERATOR_DATA_H +#define _LIBCPP___CXX03___ITERATOR_DATA_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -46,4 +46,4 @@ _LIBCPP_HIDE_FROM_ABI constexpr const _Ep* data(initializer_list<_Ep> __il) noex _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_DATA_H +#endif // _LIBCPP___CXX03___ITERATOR_DATA_H diff --git a/libcxx/include/__cxx03/__iterator/default_sentinel.h b/libcxx/include/__cxx03/__iterator/default_sentinel.h index fd05aeb59bce6..7e1099a3d11c5 100644 --- a/libcxx/include/__cxx03/__iterator/default_sentinel.h +++ b/libcxx/include/__cxx03/__iterator/default_sentinel.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H -#define _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H +#ifndef _LIBCPP___CXX03___ITERATOR_DEFAULT_SENTINEL_H +#define _LIBCPP___CXX03___ITERATOR_DEFAULT_SENTINEL_H #include <__cxx03/__config> @@ -27,4 +27,4 @@ inline constexpr default_sentinel_t default_sentinel{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_DEFAULT_SENTINEL_H +#endif // _LIBCPP___CXX03___ITERATOR_DEFAULT_SENTINEL_H diff --git a/libcxx/include/__cxx03/__iterator/distance.h b/libcxx/include/__cxx03/__iterator/distance.h index 20f2771efc437..91dcc32913799 100644 --- a/libcxx/include/__cxx03/__iterator/distance.h +++ b/libcxx/include/__cxx03/__iterator/distance.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_DISTANCE_H -#define _LIBCPP___ITERATOR_DISTANCE_H +#ifndef _LIBCPP___CXX03___ITERATOR_DISTANCE_H +#define _LIBCPP___CXX03___ITERATOR_DISTANCE_H #include <__cxx03/__config> #include <__cxx03/__iterator/concepts.h> @@ -96,4 +96,4 @@ inline constexpr auto distance = __distance::__fn{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_DISTANCE_H +#endif // _LIBCPP___CXX03___ITERATOR_DISTANCE_H diff --git a/libcxx/include/__cxx03/__iterator/empty.h b/libcxx/include/__cxx03/__iterator/empty.h index 0bdb951ee12dc..20f505e789c13 100644 --- a/libcxx/include/__cxx03/__iterator/empty.h +++ b/libcxx/include/__cxx03/__iterator/empty.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_EMPTY_H -#define _LIBCPP___ITERATOR_EMPTY_H +#ifndef _LIBCPP___CXX03___ITERATOR_EMPTY_H +#define _LIBCPP___CXX03___ITERATOR_EMPTY_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -42,4 +42,4 @@ template _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_EMPTY_H +#endif // _LIBCPP___CXX03___ITERATOR_EMPTY_H diff --git a/libcxx/include/__cxx03/__iterator/erase_if_container.h b/libcxx/include/__cxx03/__iterator/erase_if_container.h index 11edc9c1312c6..c83eccd133d1f 100644 --- a/libcxx/include/__cxx03/__iterator/erase_if_container.h +++ b/libcxx/include/__cxx03/__iterator/erase_if_container.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H -#define _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H +#ifndef _LIBCPP___CXX03___ITERATOR_ERASE_IF_CONTAINER_H +#define _LIBCPP___CXX03___ITERATOR_ERASE_IF_CONTAINER_H #include <__cxx03/__config> @@ -40,4 +40,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_ERASE_IF_CONTAINER_H +#endif // _LIBCPP___CXX03___ITERATOR_ERASE_IF_CONTAINER_H diff --git a/libcxx/include/__cxx03/__iterator/front_insert_iterator.h b/libcxx/include/__cxx03/__iterator/front_insert_iterator.h index f28b82840f2d6..9c2b987806f5b 100644 --- a/libcxx/include/__cxx03/__iterator/front_insert_iterator.h +++ b/libcxx/include/__cxx03/__iterator/front_insert_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H -#define _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_FRONT_INSERT_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_FRONT_INSERT_ITERATOR_H #include <__cxx03/__config> #include <__cxx03/__iterator/iterator.h> @@ -80,4 +80,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_FRONT_INSERT_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_FRONT_INSERT_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/incrementable_traits.h b/libcxx/include/__cxx03/__iterator/incrementable_traits.h index 8eb730bfe8ad9..e861f80ecb4d6 100644 --- a/libcxx/include/__cxx03/__iterator/incrementable_traits.h +++ b/libcxx/include/__cxx03/__iterator/incrementable_traits.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H -#define _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H +#ifndef _LIBCPP___CXX03___ITERATOR_INCREMENTABLE_TRAITS_H +#define _LIBCPP___CXX03___ITERATOR_INCREMENTABLE_TRAITS_H #include <__cxx03/__concepts/arithmetic.h> #include <__cxx03/__config> @@ -76,4 +76,4 @@ using iter_difference_t = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_INCREMENTABLE_TRAITS_H +#endif // _LIBCPP___CXX03___ITERATOR_INCREMENTABLE_TRAITS_H diff --git a/libcxx/include/__cxx03/__iterator/indirectly_comparable.h b/libcxx/include/__cxx03/__iterator/indirectly_comparable.h index caef64e6f0831..56de2de09eccd 100644 --- a/libcxx/include/__cxx03/__iterator/indirectly_comparable.h +++ b/libcxx/include/__cxx03/__iterator/indirectly_comparable.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H -#define _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H +#ifndef _LIBCPP___CXX03___ITERATOR_INDIRECTLY_COMPARABLE_H +#define _LIBCPP___CXX03___ITERATOR_INDIRECTLY_COMPARABLE_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -30,4 +30,4 @@ concept indirectly_comparable = indirect_binary_predicate<_Rp, projected<_I1, _P _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_INDIRECTLY_COMPARABLE_H +#endif // _LIBCPP___CXX03___ITERATOR_INDIRECTLY_COMPARABLE_H diff --git a/libcxx/include/__cxx03/__iterator/insert_iterator.h b/libcxx/include/__cxx03/__iterator/insert_iterator.h index 1f0320acda854..ef063ab73fced 100644 --- a/libcxx/include/__cxx03/__iterator/insert_iterator.h +++ b/libcxx/include/__cxx03/__iterator/insert_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_INSERT_ITERATOR_H -#define _LIBCPP___ITERATOR_INSERT_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_INSERT_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_INSERT_ITERATOR_H #include <__cxx03/__config> #include <__cxx03/__iterator/iterator.h> @@ -92,4 +92,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_INSERT_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_INSERT_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/istream_iterator.h b/libcxx/include/__cxx03/__iterator/istream_iterator.h index af0f477358a7f..71ca4ebc4a384 100644 --- a/libcxx/include/__cxx03/__iterator/istream_iterator.h +++ b/libcxx/include/__cxx03/__iterator/istream_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H -#define _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_ISTREAM_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_ISTREAM_ITERATOR_H #include <__cxx03/__config> #include <__cxx03/__fwd/istream.h> @@ -98,4 +98,4 @@ inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const istream_iterator<_Tp, _CharT, _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_ISTREAM_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_ISTREAM_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/istreambuf_iterator.h b/libcxx/include/__cxx03/__iterator/istreambuf_iterator.h index 73da595172848..768747d490cc0 100644 --- a/libcxx/include/__cxx03/__iterator/istreambuf_iterator.h +++ b/libcxx/include/__cxx03/__iterator/istreambuf_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H -#define _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_ISTREAMBUF_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_ISTREAMBUF_ITERATOR_H #include <__cxx03/__config> #include <__cxx03/__fwd/istream.h> @@ -106,4 +106,4 @@ operator!=(const istreambuf_iterator<_CharT, _Traits>& __a, const istreambuf_ite _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_ISTREAMBUF_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_ISTREAMBUF_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/iter_move.h b/libcxx/include/__cxx03/__iterator/iter_move.h index f45baaaf63c1e..ad33ea065f003 100644 --- a/libcxx/include/__cxx03/__iterator/iter_move.h +++ b/libcxx/include/__cxx03/__iterator/iter_move.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_ITER_MOVE_H -#define _LIBCPP___ITERATOR_ITER_MOVE_H +#ifndef _LIBCPP___CXX03___ITERATOR_ITER_MOVE_H +#define _LIBCPP___CXX03___ITERATOR_ITER_MOVE_H #include <__cxx03/__concepts/class_or_enum.h> #include <__cxx03/__config> @@ -100,4 +100,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_ITER_MOVE_H +#endif // _LIBCPP___CXX03___ITERATOR_ITER_MOVE_H diff --git a/libcxx/include/__cxx03/__iterator/iter_swap.h b/libcxx/include/__cxx03/__iterator/iter_swap.h index c3a7e164ff6f6..b61092dee724f 100644 --- a/libcxx/include/__cxx03/__iterator/iter_swap.h +++ b/libcxx/include/__cxx03/__iterator/iter_swap.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_ITER_SWAP_H -#define _LIBCPP___ITERATOR_ITER_SWAP_H +#ifndef _LIBCPP___CXX03___ITERATOR_ITER_SWAP_H +#define _LIBCPP___CXX03___ITERATOR_ITER_SWAP_H #include <__cxx03/__concepts/class_or_enum.h> #include <__cxx03/__concepts/swappable.h> @@ -105,4 +105,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_ITER_SWAP_H +#endif // _LIBCPP___CXX03___ITERATOR_ITER_SWAP_H diff --git a/libcxx/include/__cxx03/__iterator/iterator.h b/libcxx/include/__cxx03/__iterator/iterator.h index 5d9648ce6a06f..60114ffc5b4dc 100644 --- a/libcxx/include/__cxx03/__iterator/iterator.h +++ b/libcxx/include/__cxx03/__iterator/iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_ITERATOR_H -#define _LIBCPP___ITERATOR_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_ITERATOR_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -30,4 +30,4 @@ struct _LIBCPP_TEMPLATE_VIS _LIBCPP_DEPRECATED_IN_CXX17 iterator { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/iterator_traits.h b/libcxx/include/__cxx03/__iterator/iterator_traits.h index 7efd0c81c9301..66bab3ddd7e57 100644 --- a/libcxx/include/__cxx03/__iterator/iterator_traits.h +++ b/libcxx/include/__cxx03/__iterator/iterator_traits.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_ITERATOR_TRAITS_H -#define _LIBCPP___ITERATOR_ITERATOR_TRAITS_H +#ifndef _LIBCPP___CXX03___ITERATOR_ITERATOR_TRAITS_H +#define _LIBCPP___CXX03___ITERATOR_ITERATOR_TRAITS_H #include <__cxx03/__concepts/arithmetic.h> #include <__cxx03/__concepts/constructible.h> @@ -525,4 +525,4 @@ using iter_value_t = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_ITERATOR_TRAITS_H +#endif // _LIBCPP___CXX03___ITERATOR_ITERATOR_TRAITS_H diff --git a/libcxx/include/__cxx03/__iterator/iterator_with_data.h b/libcxx/include/__cxx03/__iterator/iterator_with_data.h index fb7aafc38a30c..e6aa66922237b 100644 --- a/libcxx/include/__cxx03/__iterator/iterator_with_data.h +++ b/libcxx/include/__cxx03/__iterator/iterator_with_data.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H -#define _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H +#ifndef _LIBCPP___CXX03___ITERATOR_ITERATOR_WITH_DATA_H +#define _LIBCPP___CXX03___ITERATOR_ITERATOR_WITH_DATA_H #include <__cxx03/__compare/compare_three_way_result.h> #include <__cxx03/__compare/three_way_comparable.h> @@ -102,4 +102,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_ITERATOR_WITH_DATA_H +#endif // _LIBCPP___CXX03___ITERATOR_ITERATOR_WITH_DATA_H diff --git a/libcxx/include/__cxx03/__iterator/mergeable.h b/libcxx/include/__cxx03/__iterator/mergeable.h index a20134defa87f..5e54fd28a33ff 100644 --- a/libcxx/include/__cxx03/__iterator/mergeable.h +++ b/libcxx/include/__cxx03/__iterator/mergeable.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_MERGEABLE_H -#define _LIBCPP___ITERATOR_MERGEABLE_H +#ifndef _LIBCPP___CXX03___ITERATOR_MERGEABLE_H +#define _LIBCPP___CXX03___ITERATOR_MERGEABLE_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -39,4 +39,4 @@ concept mergeable = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_MERGEABLE_H +#endif // _LIBCPP___CXX03___ITERATOR_MERGEABLE_H diff --git a/libcxx/include/__cxx03/__iterator/move_iterator.h b/libcxx/include/__cxx03/__iterator/move_iterator.h index 701f51a272da6..0fbcfdd0c1d9f 100644 --- a/libcxx/include/__cxx03/__iterator/move_iterator.h +++ b/libcxx/include/__cxx03/__iterator/move_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_MOVE_ITERATOR_H -#define _LIBCPP___ITERATOR_MOVE_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_MOVE_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_MOVE_ITERATOR_H #include <__cxx03/__compare/compare_three_way_result.h> #include <__cxx03/__compare/three_way_comparable.h> @@ -344,4 +344,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_MOVE_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_MOVE_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/move_sentinel.h b/libcxx/include/__cxx03/__iterator/move_sentinel.h index 8518bcf39ea96..cb4cf95a8c6ec 100644 --- a/libcxx/include/__cxx03/__iterator/move_sentinel.h +++ b/libcxx/include/__cxx03/__iterator/move_sentinel.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_MOVE_SENTINEL_H -#define _LIBCPP___ITERATOR_MOVE_SENTINEL_H +#ifndef _LIBCPP___CXX03___ITERATOR_MOVE_SENTINEL_H +#define _LIBCPP___CXX03___ITERATOR_MOVE_SENTINEL_H #include <__cxx03/__concepts/assignable.h> #include <__cxx03/__concepts/convertible_to.h> @@ -58,4 +58,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___ITERATOR_MOVE_SENTINEL_H +#endif // _LIBCPP___CXX03___ITERATOR_MOVE_SENTINEL_H diff --git a/libcxx/include/__cxx03/__iterator/next.h b/libcxx/include/__cxx03/__iterator/next.h index 554760347606e..459702fd43743 100644 --- a/libcxx/include/__cxx03/__iterator/next.h +++ b/libcxx/include/__cxx03/__iterator/next.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_NEXT_H -#define _LIBCPP___ITERATOR_NEXT_H +#ifndef _LIBCPP___CXX03___ITERATOR_NEXT_H +#define _LIBCPP___CXX03___ITERATOR_NEXT_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -80,4 +80,4 @@ inline constexpr auto next = __next::__fn{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_NEXT_H +#endif // _LIBCPP___CXX03___ITERATOR_NEXT_H diff --git a/libcxx/include/__cxx03/__iterator/ostream_iterator.h b/libcxx/include/__cxx03/__iterator/ostream_iterator.h index 40f737831f409..100cc54045bb3 100644 --- a/libcxx/include/__cxx03/__iterator/ostream_iterator.h +++ b/libcxx/include/__cxx03/__iterator/ostream_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H -#define _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_OSTREAM_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_OSTREAM_ITERATOR_H #include <__cxx03/__config> #include <__cxx03/__fwd/ostream.h> @@ -72,4 +72,4 @@ class _LIBCPP_TEMPLATE_VIS ostream_iterator _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_OSTREAM_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_OSTREAM_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/ostreambuf_iterator.h b/libcxx/include/__cxx03/__iterator/ostreambuf_iterator.h index 363279ce684e1..b5472b33b7711 100644 --- a/libcxx/include/__cxx03/__iterator/ostreambuf_iterator.h +++ b/libcxx/include/__cxx03/__iterator/ostreambuf_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H -#define _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_OSTREAMBUF_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_OSTREAMBUF_ITERATOR_H #include <__cxx03/__config> #include <__cxx03/__iterator/iterator.h> @@ -69,4 +69,4 @@ class _LIBCPP_TEMPLATE_VIS ostreambuf_iterator _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_OSTREAMBUF_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_OSTREAMBUF_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/permutable.h b/libcxx/include/__cxx03/__iterator/permutable.h index c2641de963de7..368c4089f1316 100644 --- a/libcxx/include/__cxx03/__iterator/permutable.h +++ b/libcxx/include/__cxx03/__iterator/permutable.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_PERMUTABLE_H -#define _LIBCPP___ITERATOR_PERMUTABLE_H +#ifndef _LIBCPP___CXX03___ITERATOR_PERMUTABLE_H +#define _LIBCPP___CXX03___ITERATOR_PERMUTABLE_H #include <__cxx03/__config> #include <__cxx03/__iterator/concepts.h> @@ -31,4 +31,4 @@ concept permutable = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_PERMUTABLE_H +#endif // _LIBCPP___CXX03___ITERATOR_PERMUTABLE_H diff --git a/libcxx/include/__cxx03/__iterator/prev.h b/libcxx/include/__cxx03/__iterator/prev.h index 7256f2d0a0faf..c272e52a9349b 100644 --- a/libcxx/include/__cxx03/__iterator/prev.h +++ b/libcxx/include/__cxx03/__iterator/prev.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_PREV_H -#define _LIBCPP___ITERATOR_PREV_H +#ifndef _LIBCPP___CXX03___ITERATOR_PREV_H +#define _LIBCPP___CXX03___ITERATOR_PREV_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -73,4 +73,4 @@ inline constexpr auto prev = __prev::__fn{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_PREV_H +#endif // _LIBCPP___CXX03___ITERATOR_PREV_H diff --git a/libcxx/include/__cxx03/__iterator/projected.h b/libcxx/include/__cxx03/__iterator/projected.h index 582d192120620..b80b7d56da890 100644 --- a/libcxx/include/__cxx03/__iterator/projected.h +++ b/libcxx/include/__cxx03/__iterator/projected.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_PROJECTED_H -#define _LIBCPP___ITERATOR_PROJECTED_H +#ifndef _LIBCPP___CXX03___ITERATOR_PROJECTED_H +#define _LIBCPP___CXX03___ITERATOR_PROJECTED_H #include <__cxx03/__config> #include <__cxx03/__iterator/concepts.h> @@ -50,4 +50,4 @@ using projected = typename __projected_impl<_It, _Proj>::__type; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_PROJECTED_H +#endif // _LIBCPP___CXX03___ITERATOR_PROJECTED_H diff --git a/libcxx/include/__cxx03/__iterator/ranges_iterator_traits.h b/libcxx/include/__cxx03/__iterator/ranges_iterator_traits.h index 0dddc16575390..b2333ace6d631 100644 --- a/libcxx/include/__cxx03/__iterator/ranges_iterator_traits.h +++ b/libcxx/include/__cxx03/__iterator/ranges_iterator_traits.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H -#define _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H +#ifndef _LIBCPP___CXX03___ITERATOR_RANGES_ITERATOR_TRAITS_H +#define _LIBCPP___CXX03___ITERATOR_RANGES_ITERATOR_TRAITS_H #include <__cxx03/__config> #include <__cxx03/__fwd/pair.h> @@ -37,4 +37,4 @@ using __range_to_alloc_type = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_RANGES_ITERATOR_TRAITS_H +#endif // _LIBCPP___CXX03___ITERATOR_RANGES_ITERATOR_TRAITS_H diff --git a/libcxx/include/__cxx03/__iterator/readable_traits.h b/libcxx/include/__cxx03/__iterator/readable_traits.h index 07ef5e30ae469..c7b21649d8a18 100644 --- a/libcxx/include/__cxx03/__iterator/readable_traits.h +++ b/libcxx/include/__cxx03/__iterator/readable_traits.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_READABLE_TRAITS_H -#define _LIBCPP___ITERATOR_READABLE_TRAITS_H +#ifndef _LIBCPP___CXX03___ITERATOR_READABLE_TRAITS_H +#define _LIBCPP___CXX03___ITERATOR_READABLE_TRAITS_H #include <__cxx03/__concepts/same_as.h> #include <__cxx03/__config> @@ -78,4 +78,4 @@ struct indirectly_readable_traits<_Tp> : __cond_value_type #include <__cxx03/__iterator/reverse_iterator.h> @@ -77,4 +77,4 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX17 auto crend(const _Cp& __c) - _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_REVERSE_ACCESS_H +#endif // _LIBCPP___CXX03___ITERATOR_REVERSE_ACCESS_H diff --git a/libcxx/include/__cxx03/__iterator/reverse_iterator.h b/libcxx/include/__cxx03/__iterator/reverse_iterator.h index 000da25a0f330..b95ca27ff5fb0 100644 --- a/libcxx/include/__cxx03/__iterator/reverse_iterator.h +++ b/libcxx/include/__cxx03/__iterator/reverse_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_REVERSE_ITERATOR_H -#define _LIBCPP___ITERATOR_REVERSE_ITERATOR_H +#ifndef _LIBCPP___CXX03___ITERATOR_REVERSE_ITERATOR_H +#define _LIBCPP___CXX03___ITERATOR_REVERSE_ITERATOR_H #include <__cxx03/__algorithm/unwrap_iter.h> #include <__cxx03/__compare/compare_three_way_result.h> @@ -343,4 +343,4 @@ struct __unwrap_iter_impl >, __b> { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_REVERSE_ITERATOR_H +#endif // _LIBCPP___CXX03___ITERATOR_REVERSE_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/segmented_iterator.h b/libcxx/include/__cxx03/__iterator/segmented_iterator.h index 93cd8e195eb05..7e353d620dc83 100644 --- a/libcxx/include/__cxx03/__iterator/segmented_iterator.h +++ b/libcxx/include/__cxx03/__iterator/segmented_iterator.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___SEGMENTED_ITERATOR_H -#define _LIBCPP___SEGMENTED_ITERATOR_H +#ifndef _LIBCPP___CXX03___SEGMENTED_ITERATOR_H +#define _LIBCPP___CXX03___SEGMENTED_ITERATOR_H // Segmented iterators are iterators over (not necessarily contiguous) sub-ranges. // @@ -76,4 +76,4 @@ using __is_segmented_iterator = __has_specialization<__segmented_iterator_traits _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___SEGMENTED_ITERATOR_H +#endif // _LIBCPP___CXX03___SEGMENTED_ITERATOR_H diff --git a/libcxx/include/__cxx03/__iterator/size.h b/libcxx/include/__cxx03/__iterator/size.h index 3e8c2537f723f..b0374a6c59e1c 100644 --- a/libcxx/include/__cxx03/__iterator/size.h +++ b/libcxx/include/__cxx03/__iterator/size.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_SIZE_H -#define _LIBCPP___ITERATOR_SIZE_H +#ifndef _LIBCPP___CXX03___ITERATOR_SIZE_H +#define _LIBCPP___CXX03___ITERATOR_SIZE_H #include <__cxx03/__config> #include <__cxx03/__type_traits/common_type.h> @@ -56,4 +56,4 @@ _LIBCPP_DIAGNOSTIC_POP _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_SIZE_H +#endif // _LIBCPP___CXX03___ITERATOR_SIZE_H diff --git a/libcxx/include/__cxx03/__iterator/sortable.h b/libcxx/include/__cxx03/__iterator/sortable.h index 5c32629ff55dc..ae82f0f615432 100644 --- a/libcxx/include/__cxx03/__iterator/sortable.h +++ b/libcxx/include/__cxx03/__iterator/sortable.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_SORTABLE_H -#define _LIBCPP___ITERATOR_SORTABLE_H +#ifndef _LIBCPP___CXX03___ITERATOR_SORTABLE_H +#define _LIBCPP___CXX03___ITERATOR_SORTABLE_H #include <__cxx03/__config> #include <__cxx03/__functional/identity.h> @@ -32,4 +32,4 @@ concept sortable = permutable<_Iter> && indirect_strict_weak_order<_Comp, projec _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_SORTABLE_H +#endif // _LIBCPP___CXX03___ITERATOR_SORTABLE_H diff --git a/libcxx/include/__cxx03/__iterator/unreachable_sentinel.h b/libcxx/include/__cxx03/__iterator/unreachable_sentinel.h index 29d76409728ff..6184692b4074a 100644 --- a/libcxx/include/__cxx03/__iterator/unreachable_sentinel.h +++ b/libcxx/include/__cxx03/__iterator/unreachable_sentinel.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_UNREACHABLE_SENTINEL_H -#define _LIBCPP___ITERATOR_UNREACHABLE_SENTINEL_H +#ifndef _LIBCPP___CXX03___ITERATOR_UNREACHABLE_SENTINEL_H +#define _LIBCPP___CXX03___ITERATOR_UNREACHABLE_SENTINEL_H #include <__cxx03/__config> #include <__cxx03/__iterator/concepts.h> @@ -34,4 +34,4 @@ inline constexpr unreachable_sentinel_t unreachable_sentinel{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_UNREACHABLE_SENTINEL_H +#endif // _LIBCPP___CXX03___ITERATOR_UNREACHABLE_SENTINEL_H diff --git a/libcxx/include/__cxx03/__iterator/wrap_iter.h b/libcxx/include/__cxx03/__iterator/wrap_iter.h index 5ef909c19f4d3..8e7df13490974 100644 --- a/libcxx/include/__cxx03/__iterator/wrap_iter.h +++ b/libcxx/include/__cxx03/__iterator/wrap_iter.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___ITERATOR_WRAP_ITER_H -#define _LIBCPP___ITERATOR_WRAP_ITER_H +#ifndef _LIBCPP___CXX03___ITERATOR_WRAP_ITER_H +#define _LIBCPP___CXX03___ITERATOR_WRAP_ITER_H #include <__cxx03/__compare/ordering.h> #include <__cxx03/__compare/three_way_comparable.h> @@ -241,4 +241,4 @@ struct _LIBCPP_TEMPLATE_VIS pointer_traits<__wrap_iter<_It> > { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___ITERATOR_WRAP_ITER_H +#endif // _LIBCPP___CXX03___ITERATOR_WRAP_ITER_H diff --git a/libcxx/include/__cxx03/__locale b/libcxx/include/__cxx03/__locale index 7324aa2390ce7..383b56a1942e8 100644 --- a/libcxx/include/__cxx03/__locale +++ b/libcxx/include/__cxx03/__locale @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LOCALE -#define _LIBCPP___LOCALE +#ifndef _LIBCPP___CXX03___LOCALE +#define _LIBCPP___CXX03___LOCALE #include <__cxx03/__config> #include <__cxx03/__locale_dir/locale_base_api.h> @@ -1510,4 +1510,4 @@ private: _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___LOCALE +#endif // _LIBCPP___CXX03___LOCALE diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h index e62ebb17765d7..a20f0952f52c3 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H -#define _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H +#ifndef _LIBCPP___CXX03___LOCALE_DIR_LOCALE_BASE_API_H +#define _LIBCPP___CXX03___LOCALE_DIR_LOCALE_BASE_API_H #if defined(_LIBCPP_MSVCRT_LIKE) # include <__cxx03/__locale_dir/locale_base_api/win32.h> @@ -95,4 +95,4 @@ except that locale_t is used instead of the current global locale. The variadic functions may be implemented as templates with a parameter pack instead of variadic functions. */ -#endif // _LIBCPP___LOCALE_DIR_LOCALE_BASE_API_H +#endif // _LIBCPP___CXX03___LOCALE_DIR_LOCALE_BASE_API_H diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api/android.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api/android.h index b943c82c62298..265dbf892a54f 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api/android.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api/android.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_ANDROID_H -#define _LIBCPP___LOCALE_LOCALE_BASE_API_ANDROID_H +#ifndef _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_ANDROID_H +#define _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_ANDROID_H #include <__cxx03/stdlib.h> @@ -47,4 +47,4 @@ inline _LIBCPP_HIDE_FROM_ABI double strtod_l(const char* __nptr, char** __endptr # endif // __NDK_MAJOR__ <= 16 #endif // __has_include() -#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_ANDROID_H +#endif // _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_ANDROID_H diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api/bsd_locale_defaults.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api/bsd_locale_defaults.h index 1f9607209842c..35bf30c07fde1 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api/bsd_locale_defaults.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api/bsd_locale_defaults.h @@ -11,8 +11,8 @@ // we will define the mapping from an internal macro to the real BSD symbol. //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H -#define _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H +#ifndef _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H +#define _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) # pragma GCC system_header @@ -33,4 +33,4 @@ #define __libcpp_asprintf_l(...) asprintf_l(__VA_ARGS__) #define __libcpp_sscanf_l(...) sscanf_l(__VA_ARGS__) -#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H +#endif // _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_BSD_LOCALE_DEFAULTS_H diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api/bsd_locale_fallbacks.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api/bsd_locale_fallbacks.h index 129cacb317ee4..e61e950a42c77 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api/bsd_locale_fallbacks.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api/bsd_locale_fallbacks.h @@ -10,8 +10,8 @@ // of those functions for non-BSD platforms. //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H -#define _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H +#ifndef _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H +#define _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H #include <__cxx03/__locale_dir/locale_base_api/locale_guard.h> #include <__cxx03/cstdio> @@ -123,4 +123,4 @@ inline _LIBCPP_ATTRIBUTE_FORMAT(__scanf__, 3, 4) int __libcpp_sscanf_l( _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H +#endif // _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_BSD_LOCALE_FALLBACKS_H diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api/fuchsia.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api/fuchsia.h index 74d017d07435d..6ee6a3a1c8755 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api/fuchsia.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api/fuchsia.h @@ -7,12 +7,12 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_FUCHSIA_H -#define _LIBCPP___LOCALE_LOCALE_BASE_API_FUCHSIA_H +#ifndef _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_FUCHSIA_H +#define _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_FUCHSIA_H #include <__cxx03/__support/xlocale/__posix_l_fallback.h> #include <__cxx03/__support/xlocale/__strtonum_fallback.h> #include <__cxx03/cstdlib> #include <__cxx03/cwchar> -#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_FUCHSIA_H +#endif // _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_FUCHSIA_H diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api/ibm.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api/ibm.h index ff4b2f8b272cd..0fab9d24d84b6 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api/ibm.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api/ibm.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_IBM_H -#define _LIBCPP___LOCALE_LOCALE_BASE_API_IBM_H +#ifndef _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_IBM_H +#define _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_IBM_H #if defined(__MVS__) # include <__cxx03/__support/ibm/locale_mgmt_zos.h> @@ -105,4 +105,4 @@ _LIBCPP_ATTRIBUTE_FORMAT(__printf__, 2, 0) int vasprintf(char** strp, const char return str_size; } -#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_IBM_H +#endif // _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_IBM_H diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api/locale_guard.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api/locale_guard.h index 17eade28f35f3..e3583634e4322 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api/locale_guard.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api/locale_guard.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H -#define _LIBCPP___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H +#ifndef _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H +#define _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H #include <__cxx03/__config> #include <__cxx03/__locale> // for locale_t @@ -75,4 +75,4 @@ struct __libcpp_locale_guard { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H +#endif // _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_LOCALE_GUARD_H diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api/musl.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api/musl.h index f67511f4a0bc5..e2d23d49c9e45 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api/musl.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api/musl.h @@ -14,8 +14,8 @@ // in Musl. //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_MUSL_H -#define _LIBCPP___LOCALE_LOCALE_BASE_API_MUSL_H +#ifndef _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_MUSL_H +#define _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_MUSL_H #include <__cxx03/cstdlib> #include <__cxx03/cwchar> @@ -28,4 +28,4 @@ inline _LIBCPP_HIDE_FROM_ABI unsigned long long strtoull_l(const char* __nptr, c return ::strtoull(__nptr, __endptr, __base); } -#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_MUSL_H +#endif // _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_MUSL_H diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api/newlib.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api/newlib.h index a8c1cff16e6d8..e52d90794556a 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api/newlib.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api/newlib.h @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_NEWLIB_H -#define _LIBCPP___LOCALE_LOCALE_BASE_API_NEWLIB_H +#ifndef _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_NEWLIB_H +#define _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_NEWLIB_H -#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_NEWLIB_H +#endif // _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_NEWLIB_H diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api/openbsd.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api/openbsd.h index effd9e0d76b1c..6b64607d484d3 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api/openbsd.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api/openbsd.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_OPENBSD_H -#define _LIBCPP___LOCALE_LOCALE_BASE_API_OPENBSD_H +#ifndef _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_OPENBSD_H +#define _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_OPENBSD_H #include <__cxx03/__support/xlocale/__strtonum_fallback.h> #include <__cxx03/clocale> @@ -16,4 +16,4 @@ #include <__cxx03/ctype.h> #include <__cxx03/cwctype> -#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_OPENBSD_H +#endif // _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_OPENBSD_H diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api/win32.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api/win32.h index 60b9435039f6d..5f85acf88e6f0 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api/win32.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api/win32.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_WIN32_H -#define _LIBCPP___LOCALE_LOCALE_BASE_API_WIN32_H +#ifndef _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_WIN32_H +#define _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_WIN32_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -232,4 +232,4 @@ _LIBCPP_EXPORTED_FROM_ABI int vasprintf_l(char** __ret, locale_t __loc, const ch // not-so-pressing FIXME: use locale to determine blank characters inline int iswblank_l(wint_t __c, locale_t /*loc*/) { return (__c == L' ' || __c == L'\t'); } -#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_WIN32_H +#endif // _LIBCPP___CXX03___LOCALE_LOCALE_BASE_API_WIN32_H diff --git a/libcxx/include/__cxx03/__math/abs.h b/libcxx/include/__cxx03/__math/abs.h index ad543e654c48b..61fc58ac22692 100644 --- a/libcxx/include/__cxx03/__math/abs.h +++ b/libcxx/include/__cxx03/__math/abs.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_ABS_H -#define _LIBCPP___MATH_ABS_H +#ifndef _LIBCPP___CXX03___MATH_ABS_H +#define _LIBCPP___CXX03___MATH_ABS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -43,4 +43,4 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double fabs(_A1 __x) _NOEXCEPT { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_ABS_H +#endif // _LIBCPP___CXX03___MATH_ABS_H diff --git a/libcxx/include/__cxx03/__math/copysign.h b/libcxx/include/__cxx03/__math/copysign.h index e70d6ee286774..d20940604c6f9 100644 --- a/libcxx/include/__cxx03/__math/copysign.h +++ b/libcxx/include/__cxx03/__math/copysign.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_COPYSIGN_H -#define _LIBCPP___MATH_COPYSIGN_H +#ifndef _LIBCPP___CXX03___MATH_COPYSIGN_H +#define _LIBCPP___CXX03___MATH_COPYSIGN_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -42,4 +42,4 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::typ _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_COPYSIGN_H +#endif // _LIBCPP___CXX03___MATH_COPYSIGN_H diff --git a/libcxx/include/__cxx03/__math/error_functions.h b/libcxx/include/__cxx03/__math/error_functions.h index 47f506096676e..25cf059989862 100644 --- a/libcxx/include/__cxx03/__math/error_functions.h +++ b/libcxx/include/__cxx03/__math/error_functions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_ERROR_FUNCTIONS_H -#define _LIBCPP___MATH_ERROR_FUNCTIONS_H +#ifndef _LIBCPP___CXX03___MATH_ERROR_FUNCTIONS_H +#define _LIBCPP___CXX03___MATH_ERROR_FUNCTIONS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -57,4 +57,4 @@ inline _LIBCPP_HIDE_FROM_ABI double erfc(_A1 __x) _NOEXCEPT { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_ERROR_FUNCTIONS_H +#endif // _LIBCPP___CXX03___MATH_ERROR_FUNCTIONS_H diff --git a/libcxx/include/__cxx03/__math/exponential_functions.h b/libcxx/include/__cxx03/__math/exponential_functions.h index 2e988e1709541..452d5d238f910 100644 --- a/libcxx/include/__cxx03/__math/exponential_functions.h +++ b/libcxx/include/__cxx03/__math/exponential_functions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_EXPONENTIAL_FUNCTIONS_H -#define _LIBCPP___MATH_EXPONENTIAL_FUNCTIONS_H +#ifndef _LIBCPP___CXX03___MATH_EXPONENTIAL_FUNCTIONS_H +#define _LIBCPP___CXX03___MATH_EXPONENTIAL_FUNCTIONS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -168,4 +168,4 @@ inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type pow(_A1 __x, _A2 _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_EXPONENTIAL_FUNCTIONS_H +#endif // _LIBCPP___CXX03___MATH_EXPONENTIAL_FUNCTIONS_H diff --git a/libcxx/include/__cxx03/__math/fdim.h b/libcxx/include/__cxx03/__math/fdim.h index 5f0c8ae34eba3..ac6fec44efcb4 100644 --- a/libcxx/include/__cxx03/__math/fdim.h +++ b/libcxx/include/__cxx03/__math/fdim.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_FDIM_H -#define _LIBCPP___MATH_FDIM_H +#ifndef _LIBCPP___CXX03___MATH_FDIM_H +#define _LIBCPP___CXX03___MATH_FDIM_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -45,4 +45,4 @@ inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type fdim(_A1 __x, _A _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_FDIM_H +#endif // _LIBCPP___CXX03___MATH_FDIM_H diff --git a/libcxx/include/__cxx03/__math/fma.h b/libcxx/include/__cxx03/__math/fma.h index b58bc1a9855f7..ce7e92a330376 100644 --- a/libcxx/include/__cxx03/__math/fma.h +++ b/libcxx/include/__cxx03/__math/fma.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_FMA_H -#define _LIBCPP___MATH_FMA_H +#ifndef _LIBCPP___CXX03___MATH_FMA_H +#define _LIBCPP___CXX03___MATH_FMA_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -52,4 +52,4 @@ inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2, _A3>::type fma(_A1 __x _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_FMA_H +#endif // _LIBCPP___CXX03___MATH_FMA_H diff --git a/libcxx/include/__cxx03/__math/gamma.h b/libcxx/include/__cxx03/__math/gamma.h index 613ff0104def4..4d104988e2c9e 100644 --- a/libcxx/include/__cxx03/__math/gamma.h +++ b/libcxx/include/__cxx03/__math/gamma.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_GAMMA_H -#define _LIBCPP___MATH_GAMMA_H +#ifndef _LIBCPP___CXX03___MATH_GAMMA_H +#define _LIBCPP___CXX03___MATH_GAMMA_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -59,4 +59,4 @@ inline _LIBCPP_HIDE_FROM_ABI double tgamma(_A1 __x) _NOEXCEPT { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_GAMMA_H +#endif // _LIBCPP___CXX03___MATH_GAMMA_H diff --git a/libcxx/include/__cxx03/__math/hyperbolic_functions.h b/libcxx/include/__cxx03/__math/hyperbolic_functions.h index 63070ee4f000d..2b765ca923cae 100644 --- a/libcxx/include/__cxx03/__math/hyperbolic_functions.h +++ b/libcxx/include/__cxx03/__math/hyperbolic_functions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_HYPERBOLIC_FUNCTIONS_H -#define _LIBCPP___MATH_HYPERBOLIC_FUNCTIONS_H +#ifndef _LIBCPP___CXX03___MATH_HYPERBOLIC_FUNCTIONS_H +#define _LIBCPP___CXX03___MATH_HYPERBOLIC_FUNCTIONS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -73,4 +73,4 @@ inline _LIBCPP_HIDE_FROM_ABI double tanh(_A1 __x) _NOEXCEPT { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_HYPERBOLIC_FUNCTIONS_H +#endif // _LIBCPP___CXX03___MATH_HYPERBOLIC_FUNCTIONS_H diff --git a/libcxx/include/__cxx03/__math/hypot.h b/libcxx/include/__cxx03/__math/hypot.h index cb032f0fd6991..bd87fef5f5ed5 100644 --- a/libcxx/include/__cxx03/__math/hypot.h +++ b/libcxx/include/__cxx03/__math/hypot.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_HYPOT_H -#define _LIBCPP___MATH_HYPOT_H +#ifndef _LIBCPP___CXX03___MATH_HYPOT_H +#define _LIBCPP___CXX03___MATH_HYPOT_H #include <__cxx03/__algorithm/max.h> #include <__cxx03/__config> @@ -106,4 +106,4 @@ _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2, _A3>::type hypot(_A1 __x, _A2 _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MATH_HYPOT_H +#endif // _LIBCPP___CXX03___MATH_HYPOT_H diff --git a/libcxx/include/__cxx03/__math/inverse_hyperbolic_functions.h b/libcxx/include/__cxx03/__math/inverse_hyperbolic_functions.h index 0701ead8a32f1..b48689d159af0 100644 --- a/libcxx/include/__cxx03/__math/inverse_hyperbolic_functions.h +++ b/libcxx/include/__cxx03/__math/inverse_hyperbolic_functions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_INVERSE_HYPERBOLIC_FUNCTIONS_H -#define _LIBCPP___MATH_INVERSE_HYPERBOLIC_FUNCTIONS_H +#ifndef _LIBCPP___CXX03___MATH_INVERSE_HYPERBOLIC_FUNCTIONS_H +#define _LIBCPP___CXX03___MATH_INVERSE_HYPERBOLIC_FUNCTIONS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -73,4 +73,4 @@ inline _LIBCPP_HIDE_FROM_ABI double atanh(_A1 __x) _NOEXCEPT { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_INVERSE_HYPERBOLIC_FUNCTIONS_H +#endif // _LIBCPP___CXX03___MATH_INVERSE_HYPERBOLIC_FUNCTIONS_H diff --git a/libcxx/include/__cxx03/__math/inverse_trigonometric_functions.h b/libcxx/include/__cxx03/__math/inverse_trigonometric_functions.h index 626295321627a..573c9b1bdc878 100644 --- a/libcxx/include/__cxx03/__math/inverse_trigonometric_functions.h +++ b/libcxx/include/__cxx03/__math/inverse_trigonometric_functions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_INVERSE_TRIGONOMETRIC_FUNCTIONS_H -#define _LIBCPP___MATH_INVERSE_TRIGONOMETRIC_FUNCTIONS_H +#ifndef _LIBCPP___CXX03___MATH_INVERSE_TRIGONOMETRIC_FUNCTIONS_H +#define _LIBCPP___CXX03___MATH_INVERSE_TRIGONOMETRIC_FUNCTIONS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -96,4 +96,4 @@ inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type atan2(_A1 __y, _ _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_INVERSE_TRIGONOMETRIC_FUNCTIONS_H +#endif // _LIBCPP___CXX03___MATH_INVERSE_TRIGONOMETRIC_FUNCTIONS_H diff --git a/libcxx/include/__cxx03/__math/logarithms.h b/libcxx/include/__cxx03/__math/logarithms.h index ad067abdb3813..25473501435cc 100644 --- a/libcxx/include/__cxx03/__math/logarithms.h +++ b/libcxx/include/__cxx03/__math/logarithms.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_LOGARITHMS_H -#define _LIBCPP___MATH_LOGARITHMS_H +#ifndef _LIBCPP___CXX03___MATH_LOGARITHMS_H +#define _LIBCPP___CXX03___MATH_LOGARITHMS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -121,4 +121,4 @@ inline _LIBCPP_HIDE_FROM_ABI double logb(_A1 __x) _NOEXCEPT { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_LOGARITHMS_H +#endif // _LIBCPP___CXX03___MATH_LOGARITHMS_H diff --git a/libcxx/include/__cxx03/__math/min_max.h b/libcxx/include/__cxx03/__math/min_max.h index 717c8cf57e866..4df5bc1ee0f77 100644 --- a/libcxx/include/__cxx03/__math/min_max.h +++ b/libcxx/include/__cxx03/__math/min_max.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_MIN_MAX_H -#define _LIBCPP___MATH_MIN_MAX_H +#ifndef _LIBCPP___CXX03___MATH_MIN_MAX_H +#define _LIBCPP___CXX03___MATH_MIN_MAX_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -71,4 +71,4 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::typ _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_MIN_MAX_H +#endif // _LIBCPP___CXX03___MATH_MIN_MAX_H diff --git a/libcxx/include/__cxx03/__math/modulo.h b/libcxx/include/__cxx03/__math/modulo.h index 4fe58b1bf45dd..5a6124187c5d2 100644 --- a/libcxx/include/__cxx03/__math/modulo.h +++ b/libcxx/include/__cxx03/__math/modulo.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_MODULO_H -#define _LIBCPP___MATH_MODULO_H +#ifndef _LIBCPP___CXX03___MATH_MODULO_H +#define _LIBCPP___CXX03___MATH_MODULO_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -60,4 +60,4 @@ inline _LIBCPP_HIDE_FROM_ABI long double modf(long double __x, long double* __y) _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_MODULO_H +#endif // _LIBCPP___CXX03___MATH_MODULO_H diff --git a/libcxx/include/__cxx03/__math/remainder.h b/libcxx/include/__cxx03/__math/remainder.h index e7d825f4c8e38..a9f750b6ddc3f 100644 --- a/libcxx/include/__cxx03/__math/remainder.h +++ b/libcxx/include/__cxx03/__math/remainder.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_REMAINDER_H -#define _LIBCPP___MATH_REMAINDER_H +#ifndef _LIBCPP___CXX03___MATH_REMAINDER_H +#define _LIBCPP___CXX03___MATH_REMAINDER_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -70,4 +70,4 @@ inline _LIBCPP_HIDE_FROM_ABI typename __promote<_A1, _A2>::type remquo(_A1 __x, _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_REMAINDER_H +#endif // _LIBCPP___CXX03___MATH_REMAINDER_H diff --git a/libcxx/include/__cxx03/__math/roots.h b/libcxx/include/__cxx03/__math/roots.h index bb78b70dcaacb..77d9eead803c6 100644 --- a/libcxx/include/__cxx03/__math/roots.h +++ b/libcxx/include/__cxx03/__math/roots.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_ROOTS_H -#define _LIBCPP___MATH_ROOTS_H +#ifndef _LIBCPP___CXX03___MATH_ROOTS_H +#define _LIBCPP___CXX03___MATH_ROOTS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -59,4 +59,4 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double cbrt(_A1 __x) _NOEXCEPT { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_ROOTS_H +#endif // _LIBCPP___CXX03___MATH_ROOTS_H diff --git a/libcxx/include/__cxx03/__math/rounding_functions.h b/libcxx/include/__cxx03/__math/rounding_functions.h index 69b021729e0ac..e146d743e974a 100644 --- a/libcxx/include/__cxx03/__math/rounding_functions.h +++ b/libcxx/include/__cxx03/__math/rounding_functions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_ROUNDING_FUNCTIONS_H -#define _LIBCPP___MATH_ROUNDING_FUNCTIONS_H +#ifndef _LIBCPP___CXX03___MATH_ROUNDING_FUNCTIONS_H +#define _LIBCPP___CXX03___MATH_ROUNDING_FUNCTIONS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -242,4 +242,4 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI double trunc(_A1 __x) _NOEXCEPT { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_ROUNDING_FUNCTIONS_H +#endif // _LIBCPP___CXX03___MATH_ROUNDING_FUNCTIONS_H diff --git a/libcxx/include/__cxx03/__math/special_functions.h b/libcxx/include/__cxx03/__math/special_functions.h index 27fb394e803e3..38832215b89d5 100644 --- a/libcxx/include/__cxx03/__math/special_functions.h +++ b/libcxx/include/__cxx03/__math/special_functions.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_SPECIAL_FUNCTIONS_H -#define _LIBCPP___MATH_SPECIAL_FUNCTIONS_H +#ifndef _LIBCPP___CXX03___MATH_SPECIAL_FUNCTIONS_H +#define _LIBCPP___CXX03___MATH_SPECIAL_FUNCTIONS_H #include <__cxx03/__config> #include <__cxx03/__math/copysign.h> @@ -81,4 +81,4 @@ _LIBCPP_HIDE_FROM_ABI double hermite(unsigned __n, _Integer __x) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_SPECIAL_FUNCTIONS_H +#endif // _LIBCPP___CXX03___MATH_SPECIAL_FUNCTIONS_H diff --git a/libcxx/include/__cxx03/__math/traits.h b/libcxx/include/__cxx03/__math/traits.h index 60823378a835b..f62509c32c008 100644 --- a/libcxx/include/__cxx03/__math/traits.h +++ b/libcxx/include/__cxx03/__math/traits.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_TRAITS_H -#define _LIBCPP___MATH_TRAITS_H +#ifndef _LIBCPP___CXX03___MATH_TRAITS_H +#define _LIBCPP___CXX03___MATH_TRAITS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -185,4 +185,4 @@ _LIBCPP_NODISCARD inline _LIBCPP_HIDE_FROM_ABI bool isunordered(_A1 __x, _A2 __y _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_TRAITS_H +#endif // _LIBCPP___CXX03___MATH_TRAITS_H diff --git a/libcxx/include/__cxx03/__math/trigonometric_functions.h b/libcxx/include/__cxx03/__math/trigonometric_functions.h index 9d99f409cb207..6c23ae6bc854f 100644 --- a/libcxx/include/__cxx03/__math/trigonometric_functions.h +++ b/libcxx/include/__cxx03/__math/trigonometric_functions.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MATH_TRIGONOMETRIC_FUNCTIONS_H -#define _LIBCPP___MATH_TRIGONOMETRIC_FUNCTIONS_H +#ifndef _LIBCPP___CXX03___MATH_TRIGONOMETRIC_FUNCTIONS_H +#define _LIBCPP___CXX03___MATH_TRIGONOMETRIC_FUNCTIONS_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -73,4 +73,4 @@ inline _LIBCPP_HIDE_FROM_ABI double tan(_A1 __x) _NOEXCEPT { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MATH_TRIGONOMETRIC_FUNCTIONS_H +#endif // _LIBCPP___CXX03___MATH_TRIGONOMETRIC_FUNCTIONS_H diff --git a/libcxx/include/__cxx03/__mbstate_t.h b/libcxx/include/__cxx03/__mbstate_t.h index 302cc5ddc4db2..6c7cfaaa8fe5b 100644 --- a/libcxx/include/__cxx03/__mbstate_t.h +++ b/libcxx/include/__cxx03/__mbstate_t.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MBSTATE_T_H -#define _LIBCPP___MBSTATE_T_H +#ifndef _LIBCPP___CXX03___MBSTATE_T_H +#define _LIBCPP___CXX03___MBSTATE_T_H #include <__cxx03/__config> @@ -51,4 +51,4 @@ # error "We don't know how to get the definition of mbstate_t without on your platform." #endif -#endif // _LIBCPP___MBSTATE_T_H +#endif // _LIBCPP___CXX03___MBSTATE_T_H diff --git a/libcxx/include/__cxx03/__mdspan/default_accessor.h b/libcxx/include/__cxx03/__mdspan/default_accessor.h index 1745f077db701..1f7c331818566 100644 --- a/libcxx/include/__cxx03/__mdspan/default_accessor.h +++ b/libcxx/include/__cxx03/__mdspan/default_accessor.h @@ -14,8 +14,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___MDSPAN_DEFAULT_ACCESSOR_H -#define _LIBCPP___MDSPAN_DEFAULT_ACCESSOR_H +#ifndef _LIBCPP___CXX03___MDSPAN_DEFAULT_ACCESSOR_H +#define _LIBCPP___CXX03___MDSPAN_DEFAULT_ACCESSOR_H #include <__cxx03/__config> #include <__cxx03/__type_traits/is_abstract.h> @@ -63,4 +63,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MDSPAN_DEFAULT_ACCESSOR_H +#endif // _LIBCPP___CXX03___MDSPAN_DEFAULT_ACCESSOR_H diff --git a/libcxx/include/__cxx03/__mdspan/extents.h b/libcxx/include/__cxx03/__mdspan/extents.h index b6f2b6abf3f61..d6fc8b8af75aa 100644 --- a/libcxx/include/__cxx03/__mdspan/extents.h +++ b/libcxx/include/__cxx03/__mdspan/extents.h @@ -14,8 +14,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___MDSPAN_EXTENTS_H -#define _LIBCPP___MDSPAN_EXTENTS_H +#ifndef _LIBCPP___CXX03___MDSPAN_EXTENTS_H +#define _LIBCPP___CXX03___MDSPAN_EXTENTS_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -529,4 +529,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MDSPAN_EXTENTS_H +#endif // _LIBCPP___CXX03___MDSPAN_EXTENTS_H diff --git a/libcxx/include/__cxx03/__mdspan/layout_left.h b/libcxx/include/__cxx03/__mdspan/layout_left.h index 017f278ab6db0..7f667238818b3 100644 --- a/libcxx/include/__cxx03/__mdspan/layout_left.h +++ b/libcxx/include/__cxx03/__mdspan/layout_left.h @@ -14,8 +14,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___MDSPAN_LAYOUT_LEFT_H -#define _LIBCPP___MDSPAN_LAYOUT_LEFT_H +#ifndef _LIBCPP___CXX03___MDSPAN_LAYOUT_LEFT_H +#define _LIBCPP___CXX03___MDSPAN_LAYOUT_LEFT_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -201,4 +201,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MDSPAN_LAYOUT_LEFT_H +#endif // _LIBCPP___CXX03___MDSPAN_LAYOUT_LEFT_H diff --git a/libcxx/include/__cxx03/__mdspan/layout_right.h b/libcxx/include/__cxx03/__mdspan/layout_right.h index 13d430cf6b5e4..12dc5a1b558d8 100644 --- a/libcxx/include/__cxx03/__mdspan/layout_right.h +++ b/libcxx/include/__cxx03/__mdspan/layout_right.h @@ -14,8 +14,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___MDSPAN_LAYOUT_RIGHT_H -#define _LIBCPP___MDSPAN_LAYOUT_RIGHT_H +#ifndef _LIBCPP___CXX03___MDSPAN_LAYOUT_RIGHT_H +#define _LIBCPP___CXX03___MDSPAN_LAYOUT_RIGHT_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -198,4 +198,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MDSPAN_LAYOUT_RIGHT_H +#endif // _LIBCPP___CXX03___MDSPAN_LAYOUT_RIGHT_H diff --git a/libcxx/include/__cxx03/__mdspan/layout_stride.h b/libcxx/include/__cxx03/__mdspan/layout_stride.h index 9b387ba6b9f60..d97ce1a55610e 100644 --- a/libcxx/include/__cxx03/__mdspan/layout_stride.h +++ b/libcxx/include/__cxx03/__mdspan/layout_stride.h @@ -14,8 +14,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___MDSPAN_LAYOUT_STRIDE_H -#define _LIBCPP___MDSPAN_LAYOUT_STRIDE_H +#ifndef _LIBCPP___CXX03___MDSPAN_LAYOUT_STRIDE_H +#define _LIBCPP___CXX03___MDSPAN_LAYOUT_STRIDE_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -363,4 +363,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MDSPAN_LAYOUT_STRIDE_H +#endif // _LIBCPP___CXX03___MDSPAN_LAYOUT_STRIDE_H diff --git a/libcxx/include/__cxx03/__mdspan/mdspan.h b/libcxx/include/__cxx03/__mdspan/mdspan.h index 253ac1cbb1c42..a1f6f00d61b71 100644 --- a/libcxx/include/__cxx03/__mdspan/mdspan.h +++ b/libcxx/include/__cxx03/__mdspan/mdspan.h @@ -14,8 +14,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___MDSPAN_MDSPAN_H -#define _LIBCPP___MDSPAN_MDSPAN_H +#ifndef _LIBCPP___CXX03___MDSPAN_MDSPAN_H +#define _LIBCPP___CXX03___MDSPAN_MDSPAN_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -316,4 +316,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MDSPAN_MDSPAN_H +#endif // _LIBCPP___CXX03___MDSPAN_MDSPAN_H diff --git a/libcxx/include/__cxx03/__memory/addressof.h b/libcxx/include/__cxx03/__memory/addressof.h index 0f6b875884448..6c88ec87be1ac 100644 --- a/libcxx/include/__cxx03/__memory/addressof.h +++ b/libcxx/include/__cxx03/__memory/addressof.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_ADDRESSOF_H -#define _LIBCPP___MEMORY_ADDRESSOF_H +#ifndef _LIBCPP___CXX03___MEMORY_ADDRESSOF_H +#define _LIBCPP___CXX03___MEMORY_ADDRESSOF_H #include <__cxx03/__config> @@ -58,4 +58,4 @@ _Tp* addressof(const _Tp&&) noexcept = delete; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_ADDRESSOF_H +#endif // _LIBCPP___CXX03___MEMORY_ADDRESSOF_H diff --git a/libcxx/include/__cxx03/__memory/align.h b/libcxx/include/__cxx03/__memory/align.h index 3ef7011bdb62f..2b2085f217364 100644 --- a/libcxx/include/__cxx03/__memory/align.h +++ b/libcxx/include/__cxx03/__memory/align.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_ALIGN_H -#define _LIBCPP___MEMORY_ALIGN_H +#ifndef _LIBCPP___CXX03___MEMORY_ALIGN_H +#define _LIBCPP___CXX03___MEMORY_ALIGN_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -22,4 +22,4 @@ _LIBCPP_EXPORTED_FROM_ABI void* align(size_t __align, size_t __sz, void*& __ptr, _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_ALIGN_H +#endif // _LIBCPP___CXX03___MEMORY_ALIGN_H diff --git a/libcxx/include/__cxx03/__memory/aligned_alloc.h b/libcxx/include/__cxx03/__memory/aligned_alloc.h index 9e864f5a7ab0d..af90baeabc140 100644 --- a/libcxx/include/__cxx03/__memory/aligned_alloc.h +++ b/libcxx/include/__cxx03/__memory/aligned_alloc.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_ALIGNED_ALLOC_H -#define _LIBCPP___MEMORY_ALIGNED_ALLOC_H +#ifndef _LIBCPP___CXX03___MEMORY_ALIGNED_ALLOC_H +#define _LIBCPP___CXX03___MEMORY_ALIGNED_ALLOC_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -61,4 +61,4 @@ inline _LIBCPP_HIDE_FROM_ABI void __libcpp_aligned_free(void* __ptr) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_ALIGNED_ALLOC_H +#endif // _LIBCPP___CXX03___MEMORY_ALIGNED_ALLOC_H diff --git a/libcxx/include/__cxx03/__memory/allocate_at_least.h b/libcxx/include/__cxx03/__memory/allocate_at_least.h index e8b4cd3a17e5f..cb1810855a01d 100644 --- a/libcxx/include/__cxx03/__memory/allocate_at_least.h +++ b/libcxx/include/__cxx03/__memory/allocate_at_least.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_ALLOCATE_AT_LEAST_H -#define _LIBCPP___MEMORY_ALLOCATE_AT_LEAST_H +#ifndef _LIBCPP___CXX03___MEMORY_ALLOCATE_AT_LEAST_H +#define _LIBCPP___CXX03___MEMORY_ALLOCATE_AT_LEAST_H #include <__cxx03/__config> #include <__cxx03/__memory/allocator_traits.h> @@ -45,4 +45,4 @@ __allocate_at_least(_Alloc& __alloc, size_t __n) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_ALLOCATE_AT_LEAST_H +#endif // _LIBCPP___CXX03___MEMORY_ALLOCATE_AT_LEAST_H diff --git a/libcxx/include/__cxx03/__memory/allocation_guard.h b/libcxx/include/__cxx03/__memory/allocation_guard.h index a84ab2de7eb9e..0a2712d1df99b 100644 --- a/libcxx/include/__cxx03/__memory/allocation_guard.h +++ b/libcxx/include/__cxx03/__memory/allocation_guard.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_ALLOCATION_GUARD_H -#define _LIBCPP___MEMORY_ALLOCATION_GUARD_H +#ifndef _LIBCPP___CXX03___MEMORY_ALLOCATION_GUARD_H +#define _LIBCPP___CXX03___MEMORY_ALLOCATION_GUARD_H #include <__cxx03/__config> #include <__cxx03/__memory/addressof.h> @@ -105,4 +105,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_ALLOCATION_GUARD_H +#endif // _LIBCPP___CXX03___MEMORY_ALLOCATION_GUARD_H diff --git a/libcxx/include/__cxx03/__memory/allocator.h b/libcxx/include/__cxx03/__memory/allocator.h index e0066c6e89b9b..06f270a0c008c 100644 --- a/libcxx/include/__cxx03/__memory/allocator.h +++ b/libcxx/include/__cxx03/__memory/allocator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_ALLOCATOR_H -#define _LIBCPP___MEMORY_ALLOCATOR_H +#ifndef _LIBCPP___CXX03___MEMORY_ALLOCATOR_H +#define _LIBCPP___CXX03___MEMORY_ALLOCATOR_H #include <__cxx03/__config> #include <__cxx03/__memory/addressof.h> @@ -265,4 +265,4 @@ inline _LIBCPP_HIDE_FROM_ABI bool operator!=(const allocator<_Tp>&, const alloca _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_ALLOCATOR_H +#endif // _LIBCPP___CXX03___MEMORY_ALLOCATOR_H diff --git a/libcxx/include/__cxx03/__memory/allocator_arg_t.h b/libcxx/include/__cxx03/__memory/allocator_arg_t.h index 5f40454dca757..3646b71e42655 100644 --- a/libcxx/include/__cxx03/__memory/allocator_arg_t.h +++ b/libcxx/include/__cxx03/__memory/allocator_arg_t.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___FUNCTIONAL_ALLOCATOR_ARG_T_H -#define _LIBCPP___FUNCTIONAL_ALLOCATOR_ARG_T_H +#ifndef _LIBCPP___CXX03___FUNCTIONAL_ALLOCATOR_ARG_T_H +#define _LIBCPP___CXX03___FUNCTIONAL_ALLOCATOR_ARG_T_H #include <__cxx03/__config> #include <__cxx03/__memory/uses_allocator.h> @@ -72,4 +72,4 @@ __user_alloc_construct_impl(integral_constant, _Tp* __storage, const _Al _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___FUNCTIONAL_ALLOCATOR_ARG_T_H +#endif // _LIBCPP___CXX03___FUNCTIONAL_ALLOCATOR_ARG_T_H diff --git a/libcxx/include/__cxx03/__memory/allocator_destructor.h b/libcxx/include/__cxx03/__memory/allocator_destructor.h index e009cd1d04aa1..2c69c91561321 100644 --- a/libcxx/include/__cxx03/__memory/allocator_destructor.h +++ b/libcxx/include/__cxx03/__memory/allocator_destructor.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_ALLOCATOR_DESTRUCTOR_H -#define _LIBCPP___MEMORY_ALLOCATOR_DESTRUCTOR_H +#ifndef _LIBCPP___CXX03___MEMORY_ALLOCATOR_DESTRUCTOR_H +#define _LIBCPP___CXX03___MEMORY_ALLOCATOR_DESTRUCTOR_H #include <__cxx03/__config> #include <__cxx03/__memory/allocator_traits.h> @@ -37,4 +37,4 @@ class __allocator_destructor { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_ALLOCATOR_DESTRUCTOR_H +#endif // _LIBCPP___CXX03___MEMORY_ALLOCATOR_DESTRUCTOR_H diff --git a/libcxx/include/__cxx03/__memory/allocator_traits.h b/libcxx/include/__cxx03/__memory/allocator_traits.h index 9833df6c50bd6..e70716c070158 100644 --- a/libcxx/include/__cxx03/__memory/allocator_traits.h +++ b/libcxx/include/__cxx03/__memory/allocator_traits.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H -#define _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H +#ifndef _LIBCPP___CXX03___MEMORY_ALLOCATOR_TRAITS_H +#define _LIBCPP___CXX03___MEMORY_ALLOCATOR_TRAITS_H #include <__cxx03/__config> #include <__cxx03/__memory/construct_at.h> @@ -421,4 +421,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_ALLOCATOR_TRAITS_H +#endif // _LIBCPP___CXX03___MEMORY_ALLOCATOR_TRAITS_H diff --git a/libcxx/include/__cxx03/__memory/assume_aligned.h b/libcxx/include/__cxx03/__memory/assume_aligned.h index 3b345d4c5c5c4..03a495aac580c 100644 --- a/libcxx/include/__cxx03/__memory/assume_aligned.h +++ b/libcxx/include/__cxx03/__memory/assume_aligned.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_ASSUME_ALIGNED_H -#define _LIBCPP___MEMORY_ASSUME_ALIGNED_H +#ifndef _LIBCPP___CXX03___MEMORY_ASSUME_ALIGNED_H +#define _LIBCPP___CXX03___MEMORY_ASSUME_ALIGNED_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -47,4 +47,4 @@ template _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_ASSUME_ALIGNED_H +#endif // _LIBCPP___CXX03___MEMORY_ASSUME_ALIGNED_H diff --git a/libcxx/include/__cxx03/__memory/auto_ptr.h b/libcxx/include/__cxx03/__memory/auto_ptr.h index f5695745d22ea..d5d541e1547a5 100644 --- a/libcxx/include/__cxx03/__memory/auto_ptr.h +++ b/libcxx/include/__cxx03/__memory/auto_ptr.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_AUTO_PTR_H -#define _LIBCPP___MEMORY_AUTO_PTR_H +#ifndef _LIBCPP___CXX03___MEMORY_AUTO_PTR_H +#define _LIBCPP___CXX03___MEMORY_AUTO_PTR_H #include <__cxx03/__config> @@ -89,4 +89,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER <= 14 || defined(_LIBCPP_ENABLE_CXX17_REMOVED_AUTO_PTR) -#endif // _LIBCPP___MEMORY_AUTO_PTR_H +#endif // _LIBCPP___CXX03___MEMORY_AUTO_PTR_H diff --git a/libcxx/include/__cxx03/__memory/builtin_new_allocator.h b/libcxx/include/__cxx03/__memory/builtin_new_allocator.h index e0284dfcff1ee..e14a57e8a0611 100644 --- a/libcxx/include/__cxx03/__memory/builtin_new_allocator.h +++ b/libcxx/include/__cxx03/__memory/builtin_new_allocator.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_BUILTIN_NEW_ALLOCATOR_H -#define _LIBCPP___MEMORY_BUILTIN_NEW_ALLOCATOR_H +#ifndef _LIBCPP___CXX03___MEMORY_BUILTIN_NEW_ALLOCATOR_H +#define _LIBCPP___CXX03___MEMORY_BUILTIN_NEW_ALLOCATOR_H #include <__cxx03/__config> #include <__cxx03/__memory/unique_ptr.h> @@ -64,4 +64,4 @@ struct __builtin_new_allocator { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_BUILTIN_NEW_ALLOCATOR_H +#endif // _LIBCPP___CXX03___MEMORY_BUILTIN_NEW_ALLOCATOR_H diff --git a/libcxx/include/__cxx03/__memory/compressed_pair.h b/libcxx/include/__cxx03/__memory/compressed_pair.h index 2af34f02772e0..086621d355d6d 100644 --- a/libcxx/include/__cxx03/__memory/compressed_pair.h +++ b/libcxx/include/__cxx03/__memory/compressed_pair.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_COMPRESSED_PAIR_H -#define _LIBCPP___MEMORY_COMPRESSED_PAIR_H +#ifndef _LIBCPP___CXX03___MEMORY_COMPRESSED_PAIR_H +#define _LIBCPP___CXX03___MEMORY_COMPRESSED_PAIR_H #include <__cxx03/__config> #include <__cxx03/__fwd/tuple.h> @@ -168,4 +168,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_COMPRESSED_PAIR_H +#endif // _LIBCPP___CXX03___MEMORY_COMPRESSED_PAIR_H diff --git a/libcxx/include/__cxx03/__memory/concepts.h b/libcxx/include/__cxx03/__memory/concepts.h index 85620202495eb..ac57609c0b5c1 100644 --- a/libcxx/include/__cxx03/__memory/concepts.h +++ b/libcxx/include/__cxx03/__memory/concepts.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_CONCEPTS_H -#define _LIBCPP___MEMORY_CONCEPTS_H +#ifndef _LIBCPP___CXX03___MEMORY_CONCEPTS_H +#define _LIBCPP___CXX03___MEMORY_CONCEPTS_H #include <__cxx03/__concepts/same_as.h> #include <__cxx03/__config> @@ -60,4 +60,4 @@ concept __nothrow_forward_range = __nothrow_input_range<_Rp> && __nothrow_forwar _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_CONCEPTS_H +#endif // _LIBCPP___CXX03___MEMORY_CONCEPTS_H diff --git a/libcxx/include/__cxx03/__memory/construct_at.h b/libcxx/include/__cxx03/__memory/construct_at.h index 090e132a67ee5..755cdbf9743d1 100644 --- a/libcxx/include/__cxx03/__memory/construct_at.h +++ b/libcxx/include/__cxx03/__memory/construct_at.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_CONSTRUCT_AT_H -#define _LIBCPP___MEMORY_CONSTRUCT_AT_H +#ifndef _LIBCPP___CXX03___MEMORY_CONSTRUCT_AT_H +#define _LIBCPP___CXX03___MEMORY_CONSTRUCT_AT_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -125,4 +125,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_CONSTRUCT_AT_H +#endif // _LIBCPP___CXX03___MEMORY_CONSTRUCT_AT_H diff --git a/libcxx/include/__cxx03/__memory/destruct_n.h b/libcxx/include/__cxx03/__memory/destruct_n.h index f5a24a67ca52c..a7dd2abd55980 100644 --- a/libcxx/include/__cxx03/__memory/destruct_n.h +++ b/libcxx/include/__cxx03/__memory/destruct_n.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_DESTRUCT_N_H -#define _LIBCPP___MEMORY_DESTRUCT_N_H +#ifndef _LIBCPP___CXX03___MEMORY_DESTRUCT_N_H +#define _LIBCPP___CXX03___MEMORY_DESTRUCT_N_H #include <__cxx03/__config> #include <__cxx03/__type_traits/integral_constant.h> @@ -60,4 +60,4 @@ struct __destruct_n { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_DESTRUCT_N_H +#endif // _LIBCPP___CXX03___MEMORY_DESTRUCT_N_H diff --git a/libcxx/include/__cxx03/__memory/inout_ptr.h b/libcxx/include/__cxx03/__memory/inout_ptr.h index bb715e3b86c6c..4fea153874030 100644 --- a/libcxx/include/__cxx03/__memory/inout_ptr.h +++ b/libcxx/include/__cxx03/__memory/inout_ptr.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___INOUT_PTR_H -#define _LIBCPP___INOUT_PTR_H +#ifndef _LIBCPP___CXX03___INOUT_PTR_H +#define _LIBCPP___CXX03___INOUT_PTR_H #include <__cxx03/__config> #include <__cxx03/__memory/addressof.h> @@ -106,4 +106,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___INOUT_PTR_H +#endif // _LIBCPP___CXX03___INOUT_PTR_H diff --git a/libcxx/include/__cxx03/__memory/out_ptr.h b/libcxx/include/__cxx03/__memory/out_ptr.h index 9aa9f33e293c0..053818bc1f51a 100644 --- a/libcxx/include/__cxx03/__memory/out_ptr.h +++ b/libcxx/include/__cxx03/__memory/out_ptr.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___OUT_PTR_H -#define _LIBCPP___OUT_PTR_H +#ifndef _LIBCPP___CXX03___OUT_PTR_H +#define _LIBCPP___CXX03___OUT_PTR_H #include <__cxx03/__config> #include <__cxx03/__memory/addressof.h> @@ -98,4 +98,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___OUT_PTR_H +#endif // _LIBCPP___CXX03___OUT_PTR_H diff --git a/libcxx/include/__cxx03/__memory/pointer_traits.h b/libcxx/include/__cxx03/__memory/pointer_traits.h index 9c480af773b70..f1206836676d4 100644 --- a/libcxx/include/__cxx03/__memory/pointer_traits.h +++ b/libcxx/include/__cxx03/__memory/pointer_traits.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_POINTER_TRAITS_H -#define _LIBCPP___MEMORY_POINTER_TRAITS_H +#ifndef _LIBCPP___CXX03___MEMORY_POINTER_TRAITS_H +#define _LIBCPP___CXX03___MEMORY_POINTER_TRAITS_H #include <__cxx03/__config> #include <__cxx03/__memory/addressof.h> @@ -304,4 +304,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_POINTER_TRAITS_H +#endif // _LIBCPP___CXX03___MEMORY_POINTER_TRAITS_H diff --git a/libcxx/include/__cxx03/__memory/ranges_construct_at.h b/libcxx/include/__cxx03/__memory/ranges_construct_at.h index f8acc9f0c21d9..db271b8572dc6 100644 --- a/libcxx/include/__cxx03/__memory/ranges_construct_at.h +++ b/libcxx/include/__cxx03/__memory/ranges_construct_at.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_RANGES_CONSTRUCT_AT_H -#define _LIBCPP___MEMORY_RANGES_CONSTRUCT_AT_H +#ifndef _LIBCPP___CXX03___MEMORY_RANGES_CONSTRUCT_AT_H +#define _LIBCPP___CXX03___MEMORY_RANGES_CONSTRUCT_AT_H #include <__cxx03/__concepts/destructible.h> #include <__cxx03/__config> @@ -121,4 +121,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_RANGES_CONSTRUCT_AT_H +#endif // _LIBCPP___CXX03___MEMORY_RANGES_CONSTRUCT_AT_H diff --git a/libcxx/include/__cxx03/__memory/ranges_uninitialized_algorithms.h b/libcxx/include/__cxx03/__memory/ranges_uninitialized_algorithms.h index f7af434847814..24e3dfa23180a 100644 --- a/libcxx/include/__cxx03/__memory/ranges_uninitialized_algorithms.h +++ b/libcxx/include/__cxx03/__memory/ranges_uninitialized_algorithms.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H -#define _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H +#ifndef _LIBCPP___CXX03___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H +#define _LIBCPP___CXX03___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H #include <__cxx03/__algorithm/in_out_result.h> #include <__cxx03/__concepts/constructible.h> @@ -322,4 +322,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H +#endif // _LIBCPP___CXX03___MEMORY_RANGES_UNINITIALIZED_ALGORITHMS_H diff --git a/libcxx/include/__cxx03/__memory/raw_storage_iterator.h b/libcxx/include/__cxx03/__memory/raw_storage_iterator.h index bde1e1e6f0304..c0f6b9151e5cb 100644 --- a/libcxx/include/__cxx03/__memory/raw_storage_iterator.h +++ b/libcxx/include/__cxx03/__memory/raw_storage_iterator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_RAW_STORAGE_ITERATOR_H -#define _LIBCPP___MEMORY_RAW_STORAGE_ITERATOR_H +#ifndef _LIBCPP___CXX03___MEMORY_RAW_STORAGE_ITERATOR_H +#define _LIBCPP___CXX03___MEMORY_RAW_STORAGE_ITERATOR_H #include <__cxx03/__config> #include <__cxx03/__iterator/iterator.h> @@ -84,4 +84,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_RAW_STORAGE_ITERATOR_H +#endif // _LIBCPP___CXX03___MEMORY_RAW_STORAGE_ITERATOR_H diff --git a/libcxx/include/__cxx03/__memory/shared_ptr.h b/libcxx/include/__cxx03/__memory/shared_ptr.h index f6322d9141e30..5e1f8c1ff7d5e 100644 --- a/libcxx/include/__cxx03/__memory/shared_ptr.h +++ b/libcxx/include/__cxx03/__memory/shared_ptr.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_SHARED_PTR_H -#define _LIBCPP___MEMORY_SHARED_PTR_H +#ifndef _LIBCPP___CXX03___MEMORY_SHARED_PTR_H +#define _LIBCPP___CXX03___MEMORY_SHARED_PTR_H #include <__cxx03/__compare/compare_three_way.h> #include <__cxx03/__compare/ordering.h> @@ -1691,4 +1691,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_SHARED_PTR_H +#endif // _LIBCPP___CXX03___MEMORY_SHARED_PTR_H diff --git a/libcxx/include/__cxx03/__memory/swap_allocator.h b/libcxx/include/__cxx03/__memory/swap_allocator.h index 3b463553d3ff5..2986da7365732 100644 --- a/libcxx/include/__cxx03/__memory/swap_allocator.h +++ b/libcxx/include/__cxx03/__memory/swap_allocator.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_SWAP_ALLOCATOR_H -#define _LIBCPP___MEMORY_SWAP_ALLOCATOR_H +#ifndef _LIBCPP___CXX03___MEMORY_SWAP_ALLOCATOR_H +#define _LIBCPP___CXX03___MEMORY_SWAP_ALLOCATOR_H #include <__cxx03/__config> #include <__cxx03/__memory/allocator_traits.h> @@ -51,4 +51,4 @@ inline _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX14 void __swap_allocator _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_SWAP_ALLOCATOR_H +#endif // _LIBCPP___CXX03___MEMORY_SWAP_ALLOCATOR_H diff --git a/libcxx/include/__cxx03/__memory/temp_value.h b/libcxx/include/__cxx03/__memory/temp_value.h index ddf963da45de4..b777c66187bd0 100644 --- a/libcxx/include/__cxx03/__memory/temp_value.h +++ b/libcxx/include/__cxx03/__memory/temp_value.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_TEMP_VALUE_H -#define _LIBCPP___MEMORY_TEMP_VALUE_H +#ifndef _LIBCPP___CXX03___MEMORY_TEMP_VALUE_H +#define _LIBCPP___CXX03___MEMORY_TEMP_VALUE_H #include <__cxx03/__config> #include <__cxx03/__memory/addressof.h> @@ -55,4 +55,4 @@ struct __temp_value { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_TEMP_VALUE_H +#endif // _LIBCPP___CXX03___MEMORY_TEMP_VALUE_H diff --git a/libcxx/include/__cxx03/__memory/temporary_buffer.h b/libcxx/include/__cxx03/__memory/temporary_buffer.h index 11a22e6db67d9..3f584a7337f06 100644 --- a/libcxx/include/__cxx03/__memory/temporary_buffer.h +++ b/libcxx/include/__cxx03/__memory/temporary_buffer.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_TEMPORARY_BUFFER_H -#define _LIBCPP___MEMORY_TEMPORARY_BUFFER_H +#ifndef _LIBCPP___CXX03___MEMORY_TEMPORARY_BUFFER_H +#define _LIBCPP___CXX03___MEMORY_TEMPORARY_BUFFER_H #include <__cxx03/__config> #include <__cxx03/__utility/pair.h> @@ -72,4 +72,4 @@ struct __return_temporary_buffer { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_TEMPORARY_BUFFER_H +#endif // _LIBCPP___CXX03___MEMORY_TEMPORARY_BUFFER_H diff --git a/libcxx/include/__cxx03/__memory/uninitialized_algorithms.h b/libcxx/include/__cxx03/__memory/uninitialized_algorithms.h index d74304d1d970a..d595c8c6cf49e 100644 --- a/libcxx/include/__cxx03/__memory/uninitialized_algorithms.h +++ b/libcxx/include/__cxx03/__memory/uninitialized_algorithms.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H -#define _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H +#ifndef _LIBCPP___CXX03___MEMORY_UNINITIALIZED_ALGORITHMS_H +#define _LIBCPP___CXX03___MEMORY_UNINITIALIZED_ALGORITHMS_H #include <__cxx03/__algorithm/copy.h> #include <__cxx03/__algorithm/move.h> @@ -650,4 +650,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_UNINITIALIZED_ALGORITHMS_H +#endif // _LIBCPP___CXX03___MEMORY_UNINITIALIZED_ALGORITHMS_H diff --git a/libcxx/include/__cxx03/__memory/unique_ptr.h b/libcxx/include/__cxx03/__memory/unique_ptr.h index 2576b6b37e7cb..415b002997591 100644 --- a/libcxx/include/__cxx03/__memory/unique_ptr.h +++ b/libcxx/include/__cxx03/__memory/unique_ptr.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_UNIQUE_PTR_H -#define _LIBCPP___MEMORY_UNIQUE_PTR_H +#ifndef _LIBCPP___CXX03___MEMORY_UNIQUE_PTR_H +#define _LIBCPP___CXX03___MEMORY_UNIQUE_PTR_H #include <__cxx03/__compare/compare_three_way.h> #include <__cxx03/__compare/compare_three_way_result.h> @@ -690,4 +690,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_UNIQUE_PTR_H +#endif // _LIBCPP___CXX03___MEMORY_UNIQUE_PTR_H diff --git a/libcxx/include/__cxx03/__memory/uses_allocator.h b/libcxx/include/__cxx03/__memory/uses_allocator.h index afdaac2d4b6fc..4fb6651c68b1d 100644 --- a/libcxx/include/__cxx03/__memory/uses_allocator.h +++ b/libcxx/include/__cxx03/__memory/uses_allocator.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_USES_ALLOCATOR_H -#define _LIBCPP___MEMORY_USES_ALLOCATOR_H +#ifndef _LIBCPP___CXX03___MEMORY_USES_ALLOCATOR_H +#define _LIBCPP___CXX03___MEMORY_USES_ALLOCATOR_H #include <__cxx03/__config> #include <__cxx03/__type_traits/is_convertible.h> @@ -49,4 +49,4 @@ inline constexpr bool uses_allocator_v = uses_allocator<_Tp, _Alloc>::value; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_USES_ALLOCATOR_H +#endif // _LIBCPP___CXX03___MEMORY_USES_ALLOCATOR_H diff --git a/libcxx/include/__cxx03/__memory/uses_allocator_construction.h b/libcxx/include/__cxx03/__memory/uses_allocator_construction.h index fae2609204b13..447d2a4e7cce1 100644 --- a/libcxx/include/__cxx03/__memory/uses_allocator_construction.h +++ b/libcxx/include/__cxx03/__memory/uses_allocator_construction.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H -#define _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H +#ifndef _LIBCPP___CXX03___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H +#define _LIBCPP___CXX03___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H #include <__cxx03/__config> #include <__cxx03/__memory/construct_at.h> @@ -244,4 +244,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H +#endif // _LIBCPP___CXX03___MEMORY_USES_ALLOCATOR_CONSTRUCTION_H diff --git a/libcxx/include/__cxx03/__memory/voidify.h b/libcxx/include/__cxx03/__memory/voidify.h index b509aecc4a18f..63e03b7d7f8f8 100644 --- a/libcxx/include/__cxx03/__memory/voidify.h +++ b/libcxx/include/__cxx03/__memory/voidify.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_VOIDIFY_H -#define _LIBCPP___MEMORY_VOIDIFY_H +#ifndef _LIBCPP___CXX03___MEMORY_VOIDIFY_H +#define _LIBCPP___CXX03___MEMORY_VOIDIFY_H #include <__cxx03/__config> #include <__cxx03/__memory/addressof.h> @@ -27,4 +27,4 @@ _LIBCPP_ALWAYS_INLINE _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 void* _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MEMORY_VOIDIFY_H +#endif // _LIBCPP___CXX03___MEMORY_VOIDIFY_H diff --git a/libcxx/include/__cxx03/__memory_resource/memory_resource.h b/libcxx/include/__cxx03/__memory_resource/memory_resource.h index e4af41a9dc0b0..6bcad87edd407 100644 --- a/libcxx/include/__cxx03/__memory_resource/memory_resource.h +++ b/libcxx/include/__cxx03/__memory_resource/memory_resource.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H -#define _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H +#ifndef _LIBCPP___CXX03___MEMORY_RESOURCE_MEMORY_RESOURCE_H +#define _LIBCPP___CXX03___MEMORY_RESOURCE_MEMORY_RESOURCE_H #include <__cxx03/__config> #include <__cxx03/__fwd/memory_resource.h> @@ -85,4 +85,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___MEMORY_RESOURCE_MEMORY_RESOURCE_H +#endif // _LIBCPP___CXX03___MEMORY_RESOURCE_MEMORY_RESOURCE_H diff --git a/libcxx/include/__cxx03/__memory_resource/monotonic_buffer_resource.h b/libcxx/include/__cxx03/__memory_resource/monotonic_buffer_resource.h index 9d418ea2289ae..f72f56ef05fc6 100644 --- a/libcxx/include/__cxx03/__memory_resource/monotonic_buffer_resource.h +++ b/libcxx/include/__cxx03/__memory_resource/monotonic_buffer_resource.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H -#define _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H +#ifndef _LIBCPP___CXX03___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H +#define _LIBCPP___CXX03___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H #include <__cxx03/__config> #include <__cxx03/__memory/addressof.h> @@ -119,4 +119,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H +#endif // _LIBCPP___CXX03___MEMORY_RESOURCE_MONOTONIC_BUFFER_RESOURCE_H diff --git a/libcxx/include/__cxx03/__memory_resource/polymorphic_allocator.h b/libcxx/include/__cxx03/__memory_resource/polymorphic_allocator.h index f615ac3811671..154f6f0f6973b 100644 --- a/libcxx/include/__cxx03/__memory_resource/polymorphic_allocator.h +++ b/libcxx/include/__cxx03/__memory_resource/polymorphic_allocator.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_RESOURCE_POLYMORPHIC_ALLOCATOR_H -#define _LIBCPP___MEMORY_RESOURCE_POLYMORPHIC_ALLOCATOR_H +#ifndef _LIBCPP___CXX03___MEMORY_RESOURCE_POLYMORPHIC_ALLOCATOR_H +#define _LIBCPP___CXX03___MEMORY_RESOURCE_POLYMORPHIC_ALLOCATOR_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -228,4 +228,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MEMORY_RESOURCE_POLYMORPHIC_ALLOCATOR_H +#endif // _LIBCPP___CXX03___MEMORY_RESOURCE_POLYMORPHIC_ALLOCATOR_H diff --git a/libcxx/include/__cxx03/__memory_resource/pool_options.h b/libcxx/include/__cxx03/__memory_resource/pool_options.h index 50f3ea5882981..ac00e22bd7f4a 100644 --- a/libcxx/include/__cxx03/__memory_resource/pool_options.h +++ b/libcxx/include/__cxx03/__memory_resource/pool_options.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_RESOURCE_POOL_OPTIONS_H -#define _LIBCPP___MEMORY_RESOURCE_POOL_OPTIONS_H +#ifndef _LIBCPP___CXX03___MEMORY_RESOURCE_POOL_OPTIONS_H +#define _LIBCPP___CXX03___MEMORY_RESOURCE_POOL_OPTIONS_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -35,4 +35,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___MEMORY_RESOURCE_POOL_OPTIONS_H +#endif // _LIBCPP___CXX03___MEMORY_RESOURCE_POOL_OPTIONS_H diff --git a/libcxx/include/__cxx03/__memory_resource/synchronized_pool_resource.h b/libcxx/include/__cxx03/__memory_resource/synchronized_pool_resource.h index f139b592eadad..c8897a3d0818e 100644 --- a/libcxx/include/__cxx03/__memory_resource/synchronized_pool_resource.h +++ b/libcxx/include/__cxx03/__memory_resource/synchronized_pool_resource.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H -#define _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H +#ifndef _LIBCPP___CXX03___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H +#define _LIBCPP___CXX03___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H #include <__cxx03/__config> #include <__cxx03/__memory_resource/memory_resource.h> @@ -89,4 +89,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H +#endif // _LIBCPP___CXX03___MEMORY_RESOURCE_SYNCHRONIZED_POOL_RESOURCE_H diff --git a/libcxx/include/__cxx03/__memory_resource/unsynchronized_pool_resource.h b/libcxx/include/__cxx03/__memory_resource/unsynchronized_pool_resource.h index d3a32da069b7e..690768546ca6f 100644 --- a/libcxx/include/__cxx03/__memory_resource/unsynchronized_pool_resource.h +++ b/libcxx/include/__cxx03/__memory_resource/unsynchronized_pool_resource.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H -#define _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H +#ifndef _LIBCPP___CXX03___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H +#define _LIBCPP___CXX03___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H #include <__cxx03/__config> #include <__cxx03/__memory_resource/memory_resource.h> @@ -103,4 +103,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 17 -#endif // _LIBCPP___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H +#endif // _LIBCPP___CXX03___MEMORY_RESOURCE_UNSYNCHRONIZED_POOL_RESOURCE_H diff --git a/libcxx/include/__cxx03/__mutex/lock_guard.h b/libcxx/include/__cxx03/__mutex/lock_guard.h index b20efc33b2a15..6760b1f20fa9e 100644 --- a/libcxx/include/__cxx03/__mutex/lock_guard.h +++ b/libcxx/include/__cxx03/__mutex/lock_guard.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MUTEX_LOCK_GUARD_H -#define _LIBCPP___MUTEX_LOCK_GUARD_H +#ifndef _LIBCPP___CXX03___MUTEX_LOCK_GUARD_H +#define _LIBCPP___CXX03___MUTEX_LOCK_GUARD_H #include <__cxx03/__config> #include <__cxx03/__mutex/tag_types.h> @@ -45,4 +45,4 @@ _LIBCPP_CTAD_SUPPORTED_FOR_TYPE(lock_guard); _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MUTEX_LOCK_GUARD_H +#endif // _LIBCPP___CXX03___MUTEX_LOCK_GUARD_H diff --git a/libcxx/include/__cxx03/__mutex/mutex.h b/libcxx/include/__cxx03/__mutex/mutex.h index 58adf2b1b2b0a..46c7546f77e32 100644 --- a/libcxx/include/__cxx03/__mutex/mutex.h +++ b/libcxx/include/__cxx03/__mutex/mutex.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MUTEX_MUTEX_H -#define _LIBCPP___MUTEX_MUTEX_H +#ifndef _LIBCPP___CXX03___MUTEX_MUTEX_H +#define _LIBCPP___CXX03___MUTEX_MUTEX_H #include <__cxx03/__config> #include <__cxx03/__thread/support.h> @@ -50,4 +50,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_HAS_NO_THREADS -#endif // _LIBCPP___MUTEX_MUTEX_H +#endif // _LIBCPP___CXX03___MUTEX_MUTEX_H diff --git a/libcxx/include/__cxx03/__mutex/once_flag.h b/libcxx/include/__cxx03/__mutex/once_flag.h index 9c467f7b274dd..73c2017f36854 100644 --- a/libcxx/include/__cxx03/__mutex/once_flag.h +++ b/libcxx/include/__cxx03/__mutex/once_flag.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MUTEX_ONCE_FLAG_H -#define _LIBCPP___MUTEX_ONCE_FLAG_H +#ifndef _LIBCPP___CXX03___MUTEX_ONCE_FLAG_H +#define _LIBCPP___CXX03___MUTEX_ONCE_FLAG_H #include <__cxx03/__config> #include <__cxx03/__functional/invoke.h> @@ -156,4 +156,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___MUTEX_ONCE_FLAG_H +#endif // _LIBCPP___CXX03___MUTEX_ONCE_FLAG_H diff --git a/libcxx/include/__cxx03/__mutex/tag_types.h b/libcxx/include/__cxx03/__mutex/tag_types.h index c9665f1dd3a7a..7beb58dabc913 100644 --- a/libcxx/include/__cxx03/__mutex/tag_types.h +++ b/libcxx/include/__cxx03/__mutex/tag_types.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MUTEX_TAG_TYPES_H -#define _LIBCPP___MUTEX_TAG_TYPES_H +#ifndef _LIBCPP___CXX03___MUTEX_TAG_TYPES_H +#define _LIBCPP___CXX03___MUTEX_TAG_TYPES_H #include <__cxx03/__config> @@ -41,4 +41,4 @@ constexpr adopt_lock_t adopt_lock = adopt_lock_t(); _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___MUTEX_TAG_TYPES_H +#endif // _LIBCPP___CXX03___MUTEX_TAG_TYPES_H diff --git a/libcxx/include/__cxx03/__mutex/unique_lock.h b/libcxx/include/__cxx03/__mutex/unique_lock.h index 8dd620d0d5a8d..1911da3828732 100644 --- a/libcxx/include/__cxx03/__mutex/unique_lock.h +++ b/libcxx/include/__cxx03/__mutex/unique_lock.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___MUTEX_UNIQUE_LOCK_H -#define _LIBCPP___MUTEX_UNIQUE_LOCK_H +#ifndef _LIBCPP___CXX03___MUTEX_UNIQUE_LOCK_H +#define _LIBCPP___CXX03___MUTEX_UNIQUE_LOCK_H #include <__cxx03/__chrono/duration.h> #include <__cxx03/__chrono/time_point.h> @@ -174,4 +174,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_HAS_NO_THREADS -#endif // _LIBCPP___MUTEX_UNIQUE_LOCK_H +#endif // _LIBCPP___CXX03___MUTEX_UNIQUE_LOCK_H diff --git a/libcxx/include/__cxx03/__node_handle b/libcxx/include/__cxx03/__node_handle index 6b3af1507c7b4..6b272f9a49fff 100644 --- a/libcxx/include/__cxx03/__node_handle +++ b/libcxx/include/__cxx03/__node_handle @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NODE_HANDLE -#define _LIBCPP___NODE_HANDLE +#ifndef _LIBCPP___CXX03___NODE_HANDLE +#define _LIBCPP___CXX03___NODE_HANDLE /* @@ -206,4 +206,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___NODE_HANDLE +#endif // _LIBCPP___CXX03___NODE_HANDLE diff --git a/libcxx/include/__cxx03/__numeric/accumulate.h b/libcxx/include/__cxx03/__numeric/accumulate.h index 243a4b05b97a3..28309201bb060 100644 --- a/libcxx/include/__cxx03/__numeric/accumulate.h +++ b/libcxx/include/__cxx03/__numeric/accumulate.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_ACCUMULATE_H -#define _LIBCPP___NUMERIC_ACCUMULATE_H +#ifndef _LIBCPP___CXX03___NUMERIC_ACCUMULATE_H +#define _LIBCPP___CXX03___NUMERIC_ACCUMULATE_H #include <__cxx03/__config> #include <__cxx03/__utility/move.h> @@ -50,4 +50,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___NUMERIC_ACCUMULATE_H +#endif // _LIBCPP___CXX03___NUMERIC_ACCUMULATE_H diff --git a/libcxx/include/__cxx03/__numeric/adjacent_difference.h b/libcxx/include/__cxx03/__numeric/adjacent_difference.h index a07d46a3892c1..ec7ba7c27f854 100644 --- a/libcxx/include/__cxx03/__numeric/adjacent_difference.h +++ b/libcxx/include/__cxx03/__numeric/adjacent_difference.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_ADJACENT_DIFFERENCE_H -#define _LIBCPP___NUMERIC_ADJACENT_DIFFERENCE_H +#ifndef _LIBCPP___CXX03___NUMERIC_ADJACENT_DIFFERENCE_H +#define _LIBCPP___CXX03___NUMERIC_ADJACENT_DIFFERENCE_H #include <__cxx03/__config> #include <__cxx03/__iterator/iterator_traits.h> @@ -65,4 +65,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___NUMERIC_ADJACENT_DIFFERENCE_H +#endif // _LIBCPP___CXX03___NUMERIC_ADJACENT_DIFFERENCE_H diff --git a/libcxx/include/__cxx03/__numeric/exclusive_scan.h b/libcxx/include/__cxx03/__numeric/exclusive_scan.h index 70b85783ed22f..877deb22fc33d 100644 --- a/libcxx/include/__cxx03/__numeric/exclusive_scan.h +++ b/libcxx/include/__cxx03/__numeric/exclusive_scan.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_EXCLUSIVE_SCAN_H -#define _LIBCPP___NUMERIC_EXCLUSIVE_SCAN_H +#ifndef _LIBCPP___CXX03___NUMERIC_EXCLUSIVE_SCAN_H +#define _LIBCPP___CXX03___NUMERIC_EXCLUSIVE_SCAN_H #include <__cxx03/__config> #include <__cxx03/__functional/operations.h> @@ -55,4 +55,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___NUMERIC_EXCLUSIVE_SCAN_H +#endif // _LIBCPP___CXX03___NUMERIC_EXCLUSIVE_SCAN_H diff --git a/libcxx/include/__cxx03/__numeric/gcd_lcm.h b/libcxx/include/__cxx03/__numeric/gcd_lcm.h index 4d1a88f23bf46..e6d3b78fdfdd6 100644 --- a/libcxx/include/__cxx03/__numeric/gcd_lcm.h +++ b/libcxx/include/__cxx03/__numeric/gcd_lcm.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_GCD_LCM_H -#define _LIBCPP___NUMERIC_GCD_LCM_H +#ifndef _LIBCPP___CXX03___NUMERIC_GCD_LCM_H +#define _LIBCPP___CXX03___NUMERIC_GCD_LCM_H #include <__cxx03/__algorithm/min.h> #include <__cxx03/__assert> @@ -129,4 +129,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___NUMERIC_GCD_LCM_H +#endif // _LIBCPP___CXX03___NUMERIC_GCD_LCM_H diff --git a/libcxx/include/__cxx03/__numeric/inclusive_scan.h b/libcxx/include/__cxx03/__numeric/inclusive_scan.h index 352161cafd498..5cac37dfc7b0d 100644 --- a/libcxx/include/__cxx03/__numeric/inclusive_scan.h +++ b/libcxx/include/__cxx03/__numeric/inclusive_scan.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_INCLUSIVE_SCAN_H -#define _LIBCPP___NUMERIC_INCLUSIVE_SCAN_H +#ifndef _LIBCPP___CXX03___NUMERIC_INCLUSIVE_SCAN_H +#define _LIBCPP___CXX03___NUMERIC_INCLUSIVE_SCAN_H #include <__cxx03/__config> #include <__cxx03/__functional/operations.h> @@ -56,4 +56,4 @@ inclusive_scan(_InputIterator __first, _InputIterator __last, _OutputIterator __ _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___NUMERIC_INCLUSIVE_SCAN_H +#endif // _LIBCPP___CXX03___NUMERIC_INCLUSIVE_SCAN_H diff --git a/libcxx/include/__cxx03/__numeric/inner_product.h b/libcxx/include/__cxx03/__numeric/inner_product.h index a5369438c7e3f..12615c3e02136 100644 --- a/libcxx/include/__cxx03/__numeric/inner_product.h +++ b/libcxx/include/__cxx03/__numeric/inner_product.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_INNER_PRODUCT_H -#define _LIBCPP___NUMERIC_INNER_PRODUCT_H +#ifndef _LIBCPP___CXX03___NUMERIC_INNER_PRODUCT_H +#define _LIBCPP___CXX03___NUMERIC_INNER_PRODUCT_H #include <__cxx03/__config> #include <__cxx03/__utility/move.h> @@ -55,4 +55,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___NUMERIC_INNER_PRODUCT_H +#endif // _LIBCPP___CXX03___NUMERIC_INNER_PRODUCT_H diff --git a/libcxx/include/__cxx03/__numeric/iota.h b/libcxx/include/__cxx03/__numeric/iota.h index fe9fb9fc37da4..f97c124700ae8 100644 --- a/libcxx/include/__cxx03/__numeric/iota.h +++ b/libcxx/include/__cxx03/__numeric/iota.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_IOTA_H -#define _LIBCPP___NUMERIC_IOTA_H +#ifndef _LIBCPP___CXX03___NUMERIC_IOTA_H +#define _LIBCPP___CXX03___NUMERIC_IOTA_H #include <__cxx03/__config> @@ -27,4 +27,4 @@ iota(_ForwardIterator __first, _ForwardIterator __last, _Tp __value) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___NUMERIC_IOTA_H +#endif // _LIBCPP___CXX03___NUMERIC_IOTA_H diff --git a/libcxx/include/__cxx03/__numeric/midpoint.h b/libcxx/include/__cxx03/__numeric/midpoint.h index 2244354c79300..91771df1f77b4 100644 --- a/libcxx/include/__cxx03/__numeric/midpoint.h +++ b/libcxx/include/__cxx03/__numeric/midpoint.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_MIDPOINT_H -#define _LIBCPP___NUMERIC_MIDPOINT_H +#ifndef _LIBCPP___CXX03___NUMERIC_MIDPOINT_H +#define _LIBCPP___CXX03___NUMERIC_MIDPOINT_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -85,4 +85,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___NUMERIC_MIDPOINT_H +#endif // _LIBCPP___CXX03___NUMERIC_MIDPOINT_H diff --git a/libcxx/include/__cxx03/__numeric/partial_sum.h b/libcxx/include/__cxx03/__numeric/partial_sum.h index 1f9aa36233dd0..8dead17f1a5d1 100644 --- a/libcxx/include/__cxx03/__numeric/partial_sum.h +++ b/libcxx/include/__cxx03/__numeric/partial_sum.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_PARTIAL_SUM_H -#define _LIBCPP___NUMERIC_PARTIAL_SUM_H +#ifndef _LIBCPP___CXX03___NUMERIC_PARTIAL_SUM_H +#define _LIBCPP___CXX03___NUMERIC_PARTIAL_SUM_H #include <__cxx03/__config> #include <__cxx03/__iterator/iterator_traits.h> @@ -63,4 +63,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___NUMERIC_PARTIAL_SUM_H +#endif // _LIBCPP___CXX03___NUMERIC_PARTIAL_SUM_H diff --git a/libcxx/include/__cxx03/__numeric/pstl.h b/libcxx/include/__cxx03/__numeric/pstl.h index 365f6fabb1476..3311b40663549 100644 --- a/libcxx/include/__cxx03/__numeric/pstl.h +++ b/libcxx/include/__cxx03/__numeric/pstl.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_PSTL_H -#define _LIBCPP___NUMERIC_PSTL_H +#ifndef _LIBCPP___CXX03___NUMERIC_PSTL_H +#define _LIBCPP___CXX03___NUMERIC_PSTL_H #include <__cxx03/__config> @@ -171,4 +171,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___NUMERIC_PSTL_H +#endif // _LIBCPP___CXX03___NUMERIC_PSTL_H diff --git a/libcxx/include/__cxx03/__numeric/reduce.h b/libcxx/include/__cxx03/__numeric/reduce.h index 039954498043a..628951371f959 100644 --- a/libcxx/include/__cxx03/__numeric/reduce.h +++ b/libcxx/include/__cxx03/__numeric/reduce.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_REDUCE_H -#define _LIBCPP___NUMERIC_REDUCE_H +#ifndef _LIBCPP___CXX03___NUMERIC_REDUCE_H +#define _LIBCPP___CXX03___NUMERIC_REDUCE_H #include <__cxx03/__config> #include <__cxx03/__functional/operations.h> @@ -50,4 +50,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___NUMERIC_REDUCE_H +#endif // _LIBCPP___CXX03___NUMERIC_REDUCE_H diff --git a/libcxx/include/__cxx03/__numeric/saturation_arithmetic.h b/libcxx/include/__cxx03/__numeric/saturation_arithmetic.h index 972428e36a778..d4da500beaa10 100644 --- a/libcxx/include/__cxx03/__numeric/saturation_arithmetic.h +++ b/libcxx/include/__cxx03/__numeric/saturation_arithmetic.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_SATURATION_ARITHMETIC_H -#define _LIBCPP___NUMERIC_SATURATION_ARITHMETIC_H +#ifndef _LIBCPP___CXX03___NUMERIC_SATURATION_ARITHMETIC_H +#define _LIBCPP___CXX03___NUMERIC_SATURATION_ARITHMETIC_H #include <__cxx03/__assert> #include <__cxx03/__concepts/arithmetic.h> @@ -142,4 +142,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___NUMERIC_SATURATION_ARITHMETIC_H +#endif // _LIBCPP___CXX03___NUMERIC_SATURATION_ARITHMETIC_H diff --git a/libcxx/include/__cxx03/__numeric/transform_exclusive_scan.h b/libcxx/include/__cxx03/__numeric/transform_exclusive_scan.h index 5857c75eb2094..034c7c929964e 100644 --- a/libcxx/include/__cxx03/__numeric/transform_exclusive_scan.h +++ b/libcxx/include/__cxx03/__numeric/transform_exclusive_scan.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_TRANSFORM_EXCLUSIVE_SCAN_H -#define _LIBCPP___NUMERIC_TRANSFORM_EXCLUSIVE_SCAN_H +#ifndef _LIBCPP___CXX03___NUMERIC_TRANSFORM_EXCLUSIVE_SCAN_H +#define _LIBCPP___CXX03___NUMERIC_TRANSFORM_EXCLUSIVE_SCAN_H #include <__cxx03/__config> @@ -39,4 +39,4 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator transform_ex _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___NUMERIC_TRANSFORM_EXCLUSIVE_SCAN_H +#endif // _LIBCPP___CXX03___NUMERIC_TRANSFORM_EXCLUSIVE_SCAN_H diff --git a/libcxx/include/__cxx03/__numeric/transform_inclusive_scan.h b/libcxx/include/__cxx03/__numeric/transform_inclusive_scan.h index 31f7d52b4261f..00e9b1675b69f 100644 --- a/libcxx/include/__cxx03/__numeric/transform_inclusive_scan.h +++ b/libcxx/include/__cxx03/__numeric/transform_inclusive_scan.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_TRANSFORM_INCLUSIVE_SCAN_H -#define _LIBCPP___NUMERIC_TRANSFORM_INCLUSIVE_SCAN_H +#ifndef _LIBCPP___CXX03___NUMERIC_TRANSFORM_INCLUSIVE_SCAN_H +#define _LIBCPP___CXX03___NUMERIC_TRANSFORM_INCLUSIVE_SCAN_H #include <__cxx03/__config> #include <__cxx03/__iterator/iterator_traits.h> @@ -49,4 +49,4 @@ _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 _OutputIterator transform_in _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___NUMERIC_TRANSFORM_INCLUSIVE_SCAN_H +#endif // _LIBCPP___CXX03___NUMERIC_TRANSFORM_INCLUSIVE_SCAN_H diff --git a/libcxx/include/__cxx03/__numeric/transform_reduce.h b/libcxx/include/__cxx03/__numeric/transform_reduce.h index 5e494ff5d1b78..5ec1a59483f07 100644 --- a/libcxx/include/__cxx03/__numeric/transform_reduce.h +++ b/libcxx/include/__cxx03/__numeric/transform_reduce.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___NUMERIC_TRANSFORM_REDUCE_H -#define _LIBCPP___NUMERIC_TRANSFORM_REDUCE_H +#ifndef _LIBCPP___CXX03___NUMERIC_TRANSFORM_REDUCE_H +#define _LIBCPP___CXX03___NUMERIC_TRANSFORM_REDUCE_H #include <__cxx03/__config> #include <__cxx03/__functional/operations.h> @@ -56,4 +56,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___NUMERIC_TRANSFORM_REDUCE_H +#endif // _LIBCPP___CXX03___NUMERIC_TRANSFORM_REDUCE_H diff --git a/libcxx/include/__cxx03/__ostream/basic_ostream.h b/libcxx/include/__cxx03/__ostream/basic_ostream.h index 1f0fb9acd3871..593ddc501c050 100644 --- a/libcxx/include/__cxx03/__ostream/basic_ostream.h +++ b/libcxx/include/__cxx03/__ostream/basic_ostream.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___OSTREAM_BASIC_OSTREAM_H -#define _LIBCPP___OSTREAM_BASIC_OSTREAM_H +#ifndef _LIBCPP___CXX03___OSTREAM_BASIC_OSTREAM_H +#define _LIBCPP___CXX03___OSTREAM_BASIC_OSTREAM_H #include <__cxx03/__config> #include <__cxx03/__exception/operations.h> @@ -857,4 +857,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___OSTREAM_BASIC_OSTREAM_H +#endif // _LIBCPP___CXX03___OSTREAM_BASIC_OSTREAM_H diff --git a/libcxx/include/__cxx03/__ostream/print.h b/libcxx/include/__cxx03/__ostream/print.h index b183081405184..d7943efd60f80 100644 --- a/libcxx/include/__cxx03/__ostream/print.h +++ b/libcxx/include/__cxx03/__ostream/print.h @@ -6,8 +6,8 @@ // //===---------------------------------------------------------------------===// -#ifndef _LIBCPP___OSTREAM_PRINT_H -#define _LIBCPP___OSTREAM_PRINT_H +#ifndef _LIBCPP___CXX03___OSTREAM_PRINT_H +#define _LIBCPP___CXX03___OSTREAM_PRINT_H #include <__cxx03/__config> #include <__cxx03/__fwd/ostream.h> @@ -176,4 +176,4 @@ _LIBCPP_HIDE_FROM_ABI inline void println(ostream& __os) { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___OSTREAM_PRINT_H +#endif // _LIBCPP___CXX03___OSTREAM_PRINT_H diff --git a/libcxx/include/__cxx03/__pstl/backend.h b/libcxx/include/__cxx03/__pstl/backend.h index 9bc243746df0d..7e39c6dbc0f8d 100644 --- a/libcxx/include/__cxx03/__pstl/backend.h +++ b/libcxx/include/__cxx03/__pstl/backend.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_BACKEND_H -#define _LIBCPP___PSTL_BACKEND_H +#ifndef _LIBCPP___CXX03___PSTL_BACKEND_H +#define _LIBCPP___CXX03___PSTL_BACKEND_H #include <__cxx03/__config> #include <__cxx03/__pstl/backend_fwd.h> @@ -32,4 +32,4 @@ _LIBCPP_PUSH_MACROS _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_BACKEND_H +#endif // _LIBCPP___CXX03___PSTL_BACKEND_H diff --git a/libcxx/include/__cxx03/__pstl/backend_fwd.h b/libcxx/include/__cxx03/__pstl/backend_fwd.h index 56c8c043e4d2c..e9abd8e99c73c 100644 --- a/libcxx/include/__cxx03/__pstl/backend_fwd.h +++ b/libcxx/include/__cxx03/__pstl/backend_fwd.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_BACKEND_FWD_H -#define _LIBCPP___PSTL_BACKEND_FWD_H +#ifndef _LIBCPP___CXX03___PSTL_BACKEND_FWD_H +#define _LIBCPP___CXX03___PSTL_BACKEND_FWD_H #include <__cxx03/__config> @@ -298,4 +298,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_BACKEND_FWD_H +#endif // _LIBCPP___CXX03___PSTL_BACKEND_FWD_H diff --git a/libcxx/include/__cxx03/__pstl/backends/default.h b/libcxx/include/__cxx03/__pstl/backends/default.h index 2ad388ae50d33..7f7a5325c7d1c 100644 --- a/libcxx/include/__cxx03/__pstl/backends/default.h +++ b/libcxx/include/__cxx03/__pstl/backends/default.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_BACKENDS_DEFAULT_H -#define _LIBCPP___PSTL_BACKENDS_DEFAULT_H +#ifndef _LIBCPP___CXX03___PSTL_BACKENDS_DEFAULT_H +#define _LIBCPP___CXX03___PSTL_BACKENDS_DEFAULT_H #include <__cxx03/__algorithm/copy_n.h> #include <__cxx03/__algorithm/equal.h> @@ -500,4 +500,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_BACKENDS_DEFAULT_H +#endif // _LIBCPP___CXX03___PSTL_BACKENDS_DEFAULT_H diff --git a/libcxx/include/__cxx03/__pstl/backends/libdispatch.h b/libcxx/include/__cxx03/__pstl/backends/libdispatch.h index fb811917025a2..80260ca5b7a5b 100644 --- a/libcxx/include/__cxx03/__pstl/backends/libdispatch.h +++ b/libcxx/include/__cxx03/__pstl/backends/libdispatch.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_BACKENDS_LIBDISPATCH_H -#define _LIBCPP___PSTL_BACKENDS_LIBDISPATCH_H +#ifndef _LIBCPP___CXX03___PSTL_BACKENDS_LIBDISPATCH_H +#define _LIBCPP___CXX03___PSTL_BACKENDS_LIBDISPATCH_H #include <__cxx03/__algorithm/inplace_merge.h> #include <__cxx03/__algorithm/lower_bound.h> @@ -394,4 +394,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_BACKENDS_LIBDISPATCH_H +#endif // _LIBCPP___CXX03___PSTL_BACKENDS_LIBDISPATCH_H diff --git a/libcxx/include/__cxx03/__pstl/backends/serial.h b/libcxx/include/__cxx03/__pstl/backends/serial.h index 699c1035d9113..d0de7a1177783 100644 --- a/libcxx/include/__cxx03/__pstl/backends/serial.h +++ b/libcxx/include/__cxx03/__pstl/backends/serial.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_BACKENDS_SERIAL_H -#define _LIBCPP___PSTL_BACKENDS_SERIAL_H +#ifndef _LIBCPP___CXX03___PSTL_BACKENDS_SERIAL_H +#define _LIBCPP___CXX03___PSTL_BACKENDS_SERIAL_H #include <__cxx03/__algorithm/find_if.h> #include <__cxx03/__algorithm/for_each.h> @@ -178,4 +178,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_BACKENDS_SERIAL_H +#endif // _LIBCPP___CXX03___PSTL_BACKENDS_SERIAL_H diff --git a/libcxx/include/__cxx03/__pstl/backends/std_thread.h b/libcxx/include/__cxx03/__pstl/backends/std_thread.h index 06cd1a1c03c46..487ddda57aa25 100644 --- a/libcxx/include/__cxx03/__pstl/backends/std_thread.h +++ b/libcxx/include/__cxx03/__pstl/backends/std_thread.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_BACKENDS_STD_THREAD_H -#define _LIBCPP___PSTL_BACKENDS_STD_THREAD_H +#ifndef _LIBCPP___CXX03___PSTL_BACKENDS_STD_THREAD_H +#define _LIBCPP___CXX03___PSTL_BACKENDS_STD_THREAD_H #include <__cxx03/__config> #include <__cxx03/__pstl/backend_fwd.h> @@ -133,4 +133,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_BACKENDS_STD_THREAD_H +#endif // _LIBCPP___CXX03___PSTL_BACKENDS_STD_THREAD_H diff --git a/libcxx/include/__cxx03/__pstl/cpu_algos/any_of.h b/libcxx/include/__cxx03/__pstl/cpu_algos/any_of.h index b1b51d1679bf2..7828a7026e7d4 100644 --- a/libcxx/include/__cxx03/__pstl/cpu_algos/any_of.h +++ b/libcxx/include/__cxx03/__pstl/cpu_algos/any_of.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_CPU_ALGOS_ANY_OF_H -#define _LIBCPP___PSTL_CPU_ALGOS_ANY_OF_H +#ifndef _LIBCPP___CXX03___PSTL_CPU_ALGOS_ANY_OF_H +#define _LIBCPP___CXX03___PSTL_CPU_ALGOS_ANY_OF_H #include <__cxx03/__algorithm/any_of.h> #include <__cxx03/__assert> @@ -96,4 +96,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_CPU_ALGOS_ANY_OF_H +#endif // _LIBCPP___CXX03___PSTL_CPU_ALGOS_ANY_OF_H diff --git a/libcxx/include/__cxx03/__pstl/cpu_algos/cpu_traits.h b/libcxx/include/__cxx03/__pstl/cpu_algos/cpu_traits.h index 9538b5c94957d..770f5dd7b45da 100644 --- a/libcxx/include/__cxx03/__pstl/cpu_algos/cpu_traits.h +++ b/libcxx/include/__cxx03/__pstl/cpu_algos/cpu_traits.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_CPU_ALGOS_CPU_TRAITS_H -#define _LIBCPP___PSTL_CPU_ALGOS_CPU_TRAITS_H +#ifndef _LIBCPP___CXX03___PSTL_CPU_ALGOS_CPU_TRAITS_H +#define _LIBCPP___CXX03___PSTL_CPU_ALGOS_CPU_TRAITS_H #include <__cxx03/__config> #include <__cxx03/cstddef> @@ -83,4 +83,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_CPU_ALGOS_CPU_TRAITS_H +#endif // _LIBCPP___CXX03___PSTL_CPU_ALGOS_CPU_TRAITS_H diff --git a/libcxx/include/__cxx03/__pstl/cpu_algos/fill.h b/libcxx/include/__cxx03/__pstl/cpu_algos/fill.h index 19fac90c44010..a101efb632e6c 100644 --- a/libcxx/include/__cxx03/__pstl/cpu_algos/fill.h +++ b/libcxx/include/__cxx03/__pstl/cpu_algos/fill.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_CPU_ALGOS_FILL_H -#define _LIBCPP___PSTL_CPU_ALGOS_FILL_H +#ifndef _LIBCPP___CXX03___PSTL_CPU_ALGOS_FILL_H +#define _LIBCPP___CXX03___PSTL_CPU_ALGOS_FILL_H #include <__cxx03/__algorithm/fill.h> #include <__cxx03/__assert> @@ -63,4 +63,4 @@ struct __cpu_parallel_fill { } // namespace __pstl _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___PSTL_CPU_ALGOS_FILL_H +#endif // _LIBCPP___CXX03___PSTL_CPU_ALGOS_FILL_H diff --git a/libcxx/include/__cxx03/__pstl/cpu_algos/find_if.h b/libcxx/include/__cxx03/__pstl/cpu_algos/find_if.h index 2be1aad7ae6be..c7393c41c1f45 100644 --- a/libcxx/include/__cxx03/__pstl/cpu_algos/find_if.h +++ b/libcxx/include/__cxx03/__pstl/cpu_algos/find_if.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_CPU_ALGOS_FIND_IF_H -#define _LIBCPP___PSTL_CPU_ALGOS_FIND_IF_H +#ifndef _LIBCPP___CXX03___PSTL_CPU_ALGOS_FIND_IF_H +#define _LIBCPP___CXX03___PSTL_CPU_ALGOS_FIND_IF_H #include <__cxx03/__algorithm/find_if.h> #include <__cxx03/__assert> @@ -134,4 +134,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_CPU_ALGOS_FIND_IF_H +#endif // _LIBCPP___CXX03___PSTL_CPU_ALGOS_FIND_IF_H diff --git a/libcxx/include/__cxx03/__pstl/cpu_algos/for_each.h b/libcxx/include/__cxx03/__pstl/cpu_algos/for_each.h index 4f6f2e87342a9..9362f56b323b6 100644 --- a/libcxx/include/__cxx03/__pstl/cpu_algos/for_each.h +++ b/libcxx/include/__cxx03/__pstl/cpu_algos/for_each.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_CPU_ALGOS_FOR_EACH_H -#define _LIBCPP___PSTL_CPU_ALGOS_FOR_EACH_H +#ifndef _LIBCPP___CXX03___PSTL_CPU_ALGOS_FOR_EACH_H +#define _LIBCPP___CXX03___PSTL_CPU_ALGOS_FOR_EACH_H #include <__cxx03/__algorithm/for_each.h> #include <__cxx03/__assert> @@ -63,4 +63,4 @@ struct __cpu_parallel_for_each { } // namespace __pstl _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___PSTL_CPU_ALGOS_FOR_EACH_H +#endif // _LIBCPP___CXX03___PSTL_CPU_ALGOS_FOR_EACH_H diff --git a/libcxx/include/__cxx03/__pstl/cpu_algos/merge.h b/libcxx/include/__cxx03/__pstl/cpu_algos/merge.h index 0feb510dc60f7..9bab8b4838ef2 100644 --- a/libcxx/include/__cxx03/__pstl/cpu_algos/merge.h +++ b/libcxx/include/__cxx03/__pstl/cpu_algos/merge.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_CPU_ALGOS_MERGE_H -#define _LIBCPP___PSTL_CPU_ALGOS_MERGE_H +#ifndef _LIBCPP___CXX03___PSTL_CPU_ALGOS_MERGE_H +#define _LIBCPP___CXX03___PSTL_CPU_ALGOS_MERGE_H #include <__cxx03/__algorithm/merge.h> #include <__cxx03/__assert> @@ -82,4 +82,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_CPU_ALGOS_MERGE_H +#endif // _LIBCPP___CXX03___PSTL_CPU_ALGOS_MERGE_H diff --git a/libcxx/include/__cxx03/__pstl/cpu_algos/stable_sort.h b/libcxx/include/__cxx03/__pstl/cpu_algos/stable_sort.h index 63be0c7ac1669..c0ebb2cd0a1c7 100644 --- a/libcxx/include/__cxx03/__pstl/cpu_algos/stable_sort.h +++ b/libcxx/include/__cxx03/__pstl/cpu_algos/stable_sort.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_CPU_ALGOS_STABLE_SORT_H -#define _LIBCPP___PSTL_CPU_ALGOS_STABLE_SORT_H +#ifndef _LIBCPP___CXX03___PSTL_CPU_ALGOS_STABLE_SORT_H +#define _LIBCPP___CXX03___PSTL_CPU_ALGOS_STABLE_SORT_H #include <__cxx03/__algorithm/stable_sort.h> #include <__cxx03/__config> @@ -44,4 +44,4 @@ struct __cpu_parallel_stable_sort { } // namespace __pstl _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___PSTL_CPU_ALGOS_STABLE_SORT_H +#endif // _LIBCPP___CXX03___PSTL_CPU_ALGOS_STABLE_SORT_H diff --git a/libcxx/include/__cxx03/__pstl/cpu_algos/transform.h b/libcxx/include/__cxx03/__pstl/cpu_algos/transform.h index d82bbb588a998..500e110ac7e2e 100644 --- a/libcxx/include/__cxx03/__pstl/cpu_algos/transform.h +++ b/libcxx/include/__cxx03/__pstl/cpu_algos/transform.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_H -#define _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_H +#ifndef _LIBCPP___CXX03___PSTL_CPU_ALGOS_TRANSFORM_H +#define _LIBCPP___CXX03___PSTL_CPU_ALGOS_TRANSFORM_H #include <__cxx03/__algorithm/transform.h> #include <__cxx03/__assert> @@ -150,4 +150,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_H +#endif // _LIBCPP___CXX03___PSTL_CPU_ALGOS_TRANSFORM_H diff --git a/libcxx/include/__cxx03/__pstl/cpu_algos/transform_reduce.h b/libcxx/include/__cxx03/__pstl/cpu_algos/transform_reduce.h index 52f0ea361b3c1..38764d963fc5e 100644 --- a/libcxx/include/__cxx03/__pstl/cpu_algos/transform_reduce.h +++ b/libcxx/include/__cxx03/__pstl/cpu_algos/transform_reduce.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_REDUCE_H -#define _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_REDUCE_H +#ifndef _LIBCPP___CXX03___PSTL_CPU_ALGOS_TRANSFORM_REDUCE_H +#define _LIBCPP___CXX03___PSTL_CPU_ALGOS_TRANSFORM_REDUCE_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -213,4 +213,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_CPU_ALGOS_TRANSFORM_REDUCE_H +#endif // _LIBCPP___CXX03___PSTL_CPU_ALGOS_TRANSFORM_REDUCE_H diff --git a/libcxx/include/__cxx03/__pstl/dispatch.h b/libcxx/include/__cxx03/__pstl/dispatch.h index e223e59bb129c..39857d0eafd63 100644 --- a/libcxx/include/__cxx03/__pstl/dispatch.h +++ b/libcxx/include/__cxx03/__pstl/dispatch.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_DISPATCH_H -#define _LIBCPP___PSTL_DISPATCH_H +#ifndef _LIBCPP___CXX03___PSTL_DISPATCH_H +#define _LIBCPP___CXX03___PSTL_DISPATCH_H #include <__cxx03/__config> #include <__cxx03/__pstl/backend_fwd.h> @@ -63,4 +63,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_DISPATCH_H +#endif // _LIBCPP___CXX03___PSTL_DISPATCH_H diff --git a/libcxx/include/__cxx03/__pstl/handle_exception.h b/libcxx/include/__cxx03/__pstl/handle_exception.h index 562617a1786b3..e21146fa1eaca 100644 --- a/libcxx/include/__cxx03/__pstl/handle_exception.h +++ b/libcxx/include/__cxx03/__pstl/handle_exception.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___PSTL_HANDLE_EXCEPTION_H -#define _LIBCPP___PSTL_HANDLE_EXCEPTION_H +#ifndef _LIBCPP___CXX03___PSTL_HANDLE_EXCEPTION_H +#define _LIBCPP___CXX03___PSTL_HANDLE_EXCEPTION_H #include <__cxx03/__config> #include <__cxx03/__utility/forward.h> @@ -54,4 +54,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___PSTL_HANDLE_EXCEPTION_H +#endif // _LIBCPP___CXX03___PSTL_HANDLE_EXCEPTION_H diff --git a/libcxx/include/__cxx03/__random/bernoulli_distribution.h b/libcxx/include/__cxx03/__random/bernoulli_distribution.h index 28536442fd1d3..3c35e8c39e237 100644 --- a/libcxx/include/__cxx03/__random/bernoulli_distribution.h +++ b/libcxx/include/__cxx03/__random/bernoulli_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_BERNOULLI_DISTRIBUTION_H -#define _LIBCPP___RANDOM_BERNOULLI_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_BERNOULLI_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_BERNOULLI_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/is_valid.h> @@ -120,4 +120,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_BERNOULLI_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_BERNOULLI_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/binomial_distribution.h b/libcxx/include/__cxx03/__random/binomial_distribution.h index 3ca98e84082e1..5b703749fc7d1 100644 --- a/libcxx/include/__cxx03/__random/binomial_distribution.h +++ b/libcxx/include/__cxx03/__random/binomial_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_BINOMIAL_DISTRIBUTION_H -#define _LIBCPP___RANDOM_BINOMIAL_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_BINOMIAL_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_BINOMIAL_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/is_valid.h> @@ -195,4 +195,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_BINOMIAL_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_BINOMIAL_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/cauchy_distribution.h b/libcxx/include/__cxx03/__random/cauchy_distribution.h index b84ba03703143..cbec0b6f85554 100644 --- a/libcxx/include/__cxx03/__random/cauchy_distribution.h +++ b/libcxx/include/__cxx03/__random/cauchy_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_CAUCHY_DISTRIBUTION_H -#define _LIBCPP___RANDOM_CAUCHY_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_CAUCHY_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_CAUCHY_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/is_valid.h> @@ -136,4 +136,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_CAUCHY_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_CAUCHY_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/chi_squared_distribution.h b/libcxx/include/__cxx03/__random/chi_squared_distribution.h index 94ba5555ce41d..531c3204130d5 100644 --- a/libcxx/include/__cxx03/__random/chi_squared_distribution.h +++ b/libcxx/include/__cxx03/__random/chi_squared_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_CHI_SQUARED_DISTRIBUTION_H -#define _LIBCPP___RANDOM_CHI_SQUARED_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_CHI_SQUARED_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_CHI_SQUARED_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/gamma_distribution.h> @@ -122,4 +122,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_CHI_SQUARED_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_CHI_SQUARED_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/clamp_to_integral.h b/libcxx/include/__cxx03/__random/clamp_to_integral.h index c10783aab2c07..be89db8c6a807 100644 --- a/libcxx/include/__cxx03/__random/clamp_to_integral.h +++ b/libcxx/include/__cxx03/__random/clamp_to_integral.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_CLAMP_TO_INTEGRAL_H -#define _LIBCPP___RANDOM_CLAMP_TO_INTEGRAL_H +#ifndef _LIBCPP___CXX03___RANDOM_CLAMP_TO_INTEGRAL_H +#define _LIBCPP___CXX03___RANDOM_CLAMP_TO_INTEGRAL_H #include <__cxx03/__config> #include <__cxx03/cmath> @@ -56,4 +56,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_CLAMP_TO_INTEGRAL_H +#endif // _LIBCPP___CXX03___RANDOM_CLAMP_TO_INTEGRAL_H diff --git a/libcxx/include/__cxx03/__random/default_random_engine.h b/libcxx/include/__cxx03/__random/default_random_engine.h index 10eb00b3594ff..81fbac0b301a2 100644 --- a/libcxx/include/__cxx03/__random/default_random_engine.h +++ b/libcxx/include/__cxx03/__random/default_random_engine.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_DEFAULT_RANDOM_ENGINE_H -#define _LIBCPP___RANDOM_DEFAULT_RANDOM_ENGINE_H +#ifndef _LIBCPP___CXX03___RANDOM_DEFAULT_RANDOM_ENGINE_H +#define _LIBCPP___CXX03___RANDOM_DEFAULT_RANDOM_ENGINE_H #include <__cxx03/__config> #include <__cxx03/__random/linear_congruential_engine.h> @@ -22,4 +22,4 @@ typedef minstd_rand default_random_engine; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANDOM_DEFAULT_RANDOM_ENGINE_H +#endif // _LIBCPP___CXX03___RANDOM_DEFAULT_RANDOM_ENGINE_H diff --git a/libcxx/include/__cxx03/__random/discard_block_engine.h b/libcxx/include/__cxx03/__random/discard_block_engine.h index 2a5f877b79caa..43027f103a635 100644 --- a/libcxx/include/__cxx03/__random/discard_block_engine.h +++ b/libcxx/include/__cxx03/__random/discard_block_engine.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H -#define _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H +#ifndef _LIBCPP___CXX03___RANDOM_DISCARD_BLOCK_ENGINE_H +#define _LIBCPP___CXX03___RANDOM_DISCARD_BLOCK_ENGINE_H #include <__cxx03/__config> #include <__cxx03/__random/is_seed_sequence.h> @@ -169,4 +169,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_DISCARD_BLOCK_ENGINE_H +#endif // _LIBCPP___CXX03___RANDOM_DISCARD_BLOCK_ENGINE_H diff --git a/libcxx/include/__cxx03/__random/discrete_distribution.h b/libcxx/include/__cxx03/__random/discrete_distribution.h index 40b8bfb61dccf..b24948050c65c 100644 --- a/libcxx/include/__cxx03/__random/discrete_distribution.h +++ b/libcxx/include/__cxx03/__random/discrete_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_DISCRETE_DISTRIBUTION_H -#define _LIBCPP___RANDOM_DISCRETE_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_DISCRETE_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_DISCRETE_DISTRIBUTION_H #include <__cxx03/__algorithm/upper_bound.h> #include <__cxx03/__config> @@ -209,4 +209,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_DISCRETE_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_DISCRETE_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/exponential_distribution.h b/libcxx/include/__cxx03/__random/exponential_distribution.h index 6f49c31a1bd10..d11a6672153bd 100644 --- a/libcxx/include/__cxx03/__random/exponential_distribution.h +++ b/libcxx/include/__cxx03/__random/exponential_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H -#define _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_EXPONENTIAL_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_EXPONENTIAL_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/generate_canonical.h> @@ -129,4 +129,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_EXPONENTIAL_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_EXPONENTIAL_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/extreme_value_distribution.h b/libcxx/include/__cxx03/__random/extreme_value_distribution.h index 46c466d620d50..4207e79cdd569 100644 --- a/libcxx/include/__cxx03/__random/extreme_value_distribution.h +++ b/libcxx/include/__cxx03/__random/extreme_value_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_EXTREME_VALUE_DISTRIBUTION_H -#define _LIBCPP___RANDOM_EXTREME_VALUE_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_EXTREME_VALUE_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_EXTREME_VALUE_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/is_valid.h> @@ -136,4 +136,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_EXTREME_VALUE_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_EXTREME_VALUE_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/fisher_f_distribution.h b/libcxx/include/__cxx03/__random/fisher_f_distribution.h index 45ab47df4021b..f0050c73ca18c 100644 --- a/libcxx/include/__cxx03/__random/fisher_f_distribution.h +++ b/libcxx/include/__cxx03/__random/fisher_f_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_FISHER_F_DISTRIBUTION_H -#define _LIBCPP___RANDOM_FISHER_F_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_FISHER_F_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_FISHER_F_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/gamma_distribution.h> @@ -135,4 +135,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_FISHER_F_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_FISHER_F_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/gamma_distribution.h b/libcxx/include/__cxx03/__random/gamma_distribution.h index 694c7219452a8..a5f9917fd8f93 100644 --- a/libcxx/include/__cxx03/__random/gamma_distribution.h +++ b/libcxx/include/__cxx03/__random/gamma_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_GAMMA_DISTRIBUTION_H -#define _LIBCPP___RANDOM_GAMMA_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_GAMMA_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_GAMMA_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/exponential_distribution.h> @@ -178,4 +178,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_GAMMA_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_GAMMA_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/generate_canonical.h b/libcxx/include/__cxx03/__random/generate_canonical.h index 363f118c4f7d6..deea98fd0314b 100644 --- a/libcxx/include/__cxx03/__random/generate_canonical.h +++ b/libcxx/include/__cxx03/__random/generate_canonical.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_GENERATE_CANONICAL_H -#define _LIBCPP___RANDOM_GENERATE_CANONICAL_H +#ifndef _LIBCPP___CXX03___RANDOM_GENERATE_CANONICAL_H +#define _LIBCPP___CXX03___RANDOM_GENERATE_CANONICAL_H #include <__cxx03/__config> #include <__cxx03/__random/log2.h> @@ -48,4 +48,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_GENERATE_CANONICAL_H +#endif // _LIBCPP___CXX03___RANDOM_GENERATE_CANONICAL_H diff --git a/libcxx/include/__cxx03/__random/geometric_distribution.h b/libcxx/include/__cxx03/__random/geometric_distribution.h index 3fe06792da856..85ca5d8ebbed9 100644 --- a/libcxx/include/__cxx03/__random/geometric_distribution.h +++ b/libcxx/include/__cxx03/__random/geometric_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_GEOMETRIC_DISTRIBUTION_H -#define _LIBCPP___RANDOM_GEOMETRIC_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_GEOMETRIC_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_GEOMETRIC_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/is_valid.h> @@ -117,4 +117,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_GEOMETRIC_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_GEOMETRIC_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/independent_bits_engine.h b/libcxx/include/__cxx03/__random/independent_bits_engine.h index bf2350e7b0d6f..15df3f249ef82 100644 --- a/libcxx/include/__cxx03/__random/independent_bits_engine.h +++ b/libcxx/include/__cxx03/__random/independent_bits_engine.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_INDEPENDENT_BITS_ENGINE_H -#define _LIBCPP___RANDOM_INDEPENDENT_BITS_ENGINE_H +#ifndef _LIBCPP___CXX03___RANDOM_INDEPENDENT_BITS_ENGINE_H +#define _LIBCPP___CXX03___RANDOM_INDEPENDENT_BITS_ENGINE_H #include <__cxx03/__config> #include <__cxx03/__fwd/istream.h> @@ -202,4 +202,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_INDEPENDENT_BITS_ENGINE_H +#endif // _LIBCPP___CXX03___RANDOM_INDEPENDENT_BITS_ENGINE_H diff --git a/libcxx/include/__cxx03/__random/is_seed_sequence.h b/libcxx/include/__cxx03/__random/is_seed_sequence.h index a924857c7ffa7..ddb9c83bb7081 100644 --- a/libcxx/include/__cxx03/__random/is_seed_sequence.h +++ b/libcxx/include/__cxx03/__random/is_seed_sequence.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_IS_SEED_SEQUENCE_H -#define _LIBCPP___RANDOM_IS_SEED_SEQUENCE_H +#ifndef _LIBCPP___CXX03___RANDOM_IS_SEED_SEQUENCE_H +#define _LIBCPP___CXX03___RANDOM_IS_SEED_SEQUENCE_H #include <__cxx03/__config> #include <__cxx03/__type_traits/is_convertible.h> @@ -28,4 +28,4 @@ struct __is_seed_sequence { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANDOM_IS_SEED_SEQUENCE_H +#endif // _LIBCPP___CXX03___RANDOM_IS_SEED_SEQUENCE_H diff --git a/libcxx/include/__cxx03/__random/is_valid.h b/libcxx/include/__cxx03/__random/is_valid.h index fc32a22bf608c..65693ceecf4d0 100644 --- a/libcxx/include/__cxx03/__random/is_valid.h +++ b/libcxx/include/__cxx03/__random/is_valid.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_IS_VALID_H -#define _LIBCPP___RANDOM_IS_VALID_H +#ifndef _LIBCPP___CXX03___RANDOM_IS_VALID_H +#define _LIBCPP___CXX03___RANDOM_IS_VALID_H #include <__cxx03/__config> #include <__cxx03/__type_traits/enable_if.h> @@ -91,4 +91,4 @@ struct __libcpp_random_is_valid_urng< _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANDOM_IS_VALID_H +#endif // _LIBCPP___CXX03___RANDOM_IS_VALID_H diff --git a/libcxx/include/__cxx03/__random/knuth_b.h b/libcxx/include/__cxx03/__random/knuth_b.h index b8df0078ebb1a..0ba23d7bbd2a8 100644 --- a/libcxx/include/__cxx03/__random/knuth_b.h +++ b/libcxx/include/__cxx03/__random/knuth_b.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_KNUTH_B_H -#define _LIBCPP___RANDOM_KNUTH_B_H +#ifndef _LIBCPP___CXX03___RANDOM_KNUTH_B_H +#define _LIBCPP___CXX03___RANDOM_KNUTH_B_H #include <__cxx03/__config> #include <__cxx03/__random/linear_congruential_engine.h> @@ -23,4 +23,4 @@ typedef shuffle_order_engine knuth_b; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANDOM_KNUTH_B_H +#endif // _LIBCPP___CXX03___RANDOM_KNUTH_B_H diff --git a/libcxx/include/__cxx03/__random/linear_congruential_engine.h b/libcxx/include/__cxx03/__random/linear_congruential_engine.h index 94d140ae1a2d0..e6025571e5cc1 100644 --- a/libcxx/include/__cxx03/__random/linear_congruential_engine.h +++ b/libcxx/include/__cxx03/__random/linear_congruential_engine.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H -#define _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H +#ifndef _LIBCPP___CXX03___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H +#define _LIBCPP___CXX03___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H #include <__cxx03/__config> #include <__cxx03/__random/is_seed_sequence.h> @@ -384,4 +384,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H +#endif // _LIBCPP___CXX03___RANDOM_LINEAR_CONGRUENTIAL_ENGINE_H diff --git a/libcxx/include/__cxx03/__random/log2.h b/libcxx/include/__cxx03/__random/log2.h index 5dbaace22d86e..bea5f3c1ff4ba 100644 --- a/libcxx/include/__cxx03/__random/log2.h +++ b/libcxx/include/__cxx03/__random/log2.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_LOG2_H -#define _LIBCPP___RANDOM_LOG2_H +#ifndef _LIBCPP___CXX03___RANDOM_LOG2_H +#define _LIBCPP___CXX03___RANDOM_LOG2_H #include <__cxx03/__config> #include <__cxx03/__type_traits/conditional.h> @@ -63,4 +63,4 @@ struct __log2 { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANDOM_LOG2_H +#endif // _LIBCPP___CXX03___RANDOM_LOG2_H diff --git a/libcxx/include/__cxx03/__random/lognormal_distribution.h b/libcxx/include/__cxx03/__random/lognormal_distribution.h index f1e537a21eb65..de046d9b63562 100644 --- a/libcxx/include/__cxx03/__random/lognormal_distribution.h +++ b/libcxx/include/__cxx03/__random/lognormal_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_LOGNORMAL_DISTRIBUTION_H -#define _LIBCPP___RANDOM_LOGNORMAL_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_LOGNORMAL_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_LOGNORMAL_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/is_valid.h> @@ -123,4 +123,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_LOGNORMAL_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_LOGNORMAL_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/mersenne_twister_engine.h b/libcxx/include/__cxx03/__random/mersenne_twister_engine.h index 16deb8189dc46..d715b6ffd8dd4 100644 --- a/libcxx/include/__cxx03/__random/mersenne_twister_engine.h +++ b/libcxx/include/__cxx03/__random/mersenne_twister_engine.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H -#define _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H +#ifndef _LIBCPP___CXX03___RANDOM_MERSENNE_TWISTER_ENGINE_H +#define _LIBCPP___CXX03___RANDOM_MERSENNE_TWISTER_ENGINE_H #include <__cxx03/__algorithm/equal.h> #include <__cxx03/__algorithm/min.h> @@ -911,4 +911,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_MERSENNE_TWISTER_ENGINE_H +#endif // _LIBCPP___CXX03___RANDOM_MERSENNE_TWISTER_ENGINE_H diff --git a/libcxx/include/__cxx03/__random/negative_binomial_distribution.h b/libcxx/include/__cxx03/__random/negative_binomial_distribution.h index 6a99c87f5296b..f50b38218710f 100644 --- a/libcxx/include/__cxx03/__random/negative_binomial_distribution.h +++ b/libcxx/include/__cxx03/__random/negative_binomial_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_H -#define _LIBCPP___RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_H #include <__cxx03/__assert> #include <__cxx03/__config> @@ -154,4 +154,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_NEGATIVE_BINOMIAL_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/normal_distribution.h b/libcxx/include/__cxx03/__random/normal_distribution.h index 95e4f5da49eb4..f9700c48ade05 100644 --- a/libcxx/include/__cxx03/__random/normal_distribution.h +++ b/libcxx/include/__cxx03/__random/normal_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_NORMAL_DISTRIBUTION_H -#define _LIBCPP___RANDOM_NORMAL_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_NORMAL_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_NORMAL_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/is_valid.h> @@ -173,4 +173,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_NORMAL_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_NORMAL_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/piecewise_constant_distribution.h b/libcxx/include/__cxx03/__random/piecewise_constant_distribution.h index 5bd53b81cbfce..2036bb29ce1a6 100644 --- a/libcxx/include/__cxx03/__random/piecewise_constant_distribution.h +++ b/libcxx/include/__cxx03/__random/piecewise_constant_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_H -#define _LIBCPP___RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_H #include <__cxx03/__algorithm/upper_bound.h> #include <__cxx03/__config> @@ -299,4 +299,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_PIECEWISE_CONSTANT_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/piecewise_linear_distribution.h b/libcxx/include/__cxx03/__random/piecewise_linear_distribution.h index faf845321fec8..c871d01c37b41 100644 --- a/libcxx/include/__cxx03/__random/piecewise_linear_distribution.h +++ b/libcxx/include/__cxx03/__random/piecewise_linear_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H -#define _LIBCPP___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H #include <__cxx03/__algorithm/upper_bound.h> #include <__cxx03/__config> @@ -312,4 +312,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_PIECEWISE_LINEAR_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/poisson_distribution.h b/libcxx/include/__cxx03/__random/poisson_distribution.h index 7fb4b9681d70d..fdb30042e4a3c 100644 --- a/libcxx/include/__cxx03/__random/poisson_distribution.h +++ b/libcxx/include/__cxx03/__random/poisson_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_POISSON_DISTRIBUTION_H -#define _LIBCPP___RANDOM_POISSON_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_POISSON_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_POISSON_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/clamp_to_integral.h> @@ -238,4 +238,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_POISSON_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_POISSON_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/random_device.h b/libcxx/include/__cxx03/__random/random_device.h index 2f95979bf5491..35874bc492a0a 100644 --- a/libcxx/include/__cxx03/__random/random_device.h +++ b/libcxx/include/__cxx03/__random/random_device.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_RANDOM_DEVICE_H -#define _LIBCPP___RANDOM_RANDOM_DEVICE_H +#ifndef _LIBCPP___CXX03___RANDOM_RANDOM_DEVICE_H +#define _LIBCPP___CXX03___RANDOM_RANDOM_DEVICE_H #include <__cxx03/__config> #include <__cxx03/string> @@ -78,4 +78,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_RANDOM_DEVICE_H +#endif // _LIBCPP___CXX03___RANDOM_RANDOM_DEVICE_H diff --git a/libcxx/include/__cxx03/__random/ranlux.h b/libcxx/include/__cxx03/__random/ranlux.h index e99773cae392f..2c808f50e6382 100644 --- a/libcxx/include/__cxx03/__random/ranlux.h +++ b/libcxx/include/__cxx03/__random/ranlux.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_RANLUX_H -#define _LIBCPP___RANDOM_RANLUX_H +#ifndef _LIBCPP___CXX03___RANDOM_RANLUX_H +#define _LIBCPP___CXX03___RANDOM_RANLUX_H #include <__cxx03/__config> #include <__cxx03/__random/discard_block_engine.h> @@ -28,4 +28,4 @@ typedef discard_block_engine ranlux48; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANDOM_RANLUX_H +#endif // _LIBCPP___CXX03___RANDOM_RANLUX_H diff --git a/libcxx/include/__cxx03/__random/seed_seq.h b/libcxx/include/__cxx03/__random/seed_seq.h index 8ccd656b47e88..617ee66c819d8 100644 --- a/libcxx/include/__cxx03/__random/seed_seq.h +++ b/libcxx/include/__cxx03/__random/seed_seq.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_SEED_SEQ_H -#define _LIBCPP___RANDOM_SEED_SEQ_H +#ifndef _LIBCPP___CXX03___RANDOM_SEED_SEQ_H +#define _LIBCPP___CXX03___RANDOM_SEED_SEQ_H #include <__cxx03/__algorithm/copy.h> #include <__cxx03/__algorithm/fill.h> @@ -163,4 +163,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_SEED_SEQ_H +#endif // _LIBCPP___CXX03___RANDOM_SEED_SEQ_H diff --git a/libcxx/include/__cxx03/__random/shuffle_order_engine.h b/libcxx/include/__cxx03/__random/shuffle_order_engine.h index 8eb57c9ec56db..77eb0cf1fec87 100644 --- a/libcxx/include/__cxx03/__random/shuffle_order_engine.h +++ b/libcxx/include/__cxx03/__random/shuffle_order_engine.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_SHUFFLE_ORDER_ENGINE_H -#define _LIBCPP___RANDOM_SHUFFLE_ORDER_ENGINE_H +#ifndef _LIBCPP___CXX03___RANDOM_SHUFFLE_ORDER_ENGINE_H +#define _LIBCPP___CXX03___RANDOM_SHUFFLE_ORDER_ENGINE_H #include <__cxx03/__algorithm/equal.h> #include <__cxx03/__config> @@ -227,4 +227,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_SHUFFLE_ORDER_ENGINE_H +#endif // _LIBCPP___CXX03___RANDOM_SHUFFLE_ORDER_ENGINE_H diff --git a/libcxx/include/__cxx03/__random/student_t_distribution.h b/libcxx/include/__cxx03/__random/student_t_distribution.h index 32a1c3c7381ff..6c71d1a1a4fb8 100644 --- a/libcxx/include/__cxx03/__random/student_t_distribution.h +++ b/libcxx/include/__cxx03/__random/student_t_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_STUDENT_T_DISTRIBUTION_H -#define _LIBCPP___RANDOM_STUDENT_T_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_STUDENT_T_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_STUDENT_T_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/gamma_distribution.h> @@ -129,4 +129,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_STUDENT_T_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_STUDENT_T_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/subtract_with_carry_engine.h b/libcxx/include/__cxx03/__random/subtract_with_carry_engine.h index c539994be1c80..3a30e41bbb460 100644 --- a/libcxx/include/__cxx03/__random/subtract_with_carry_engine.h +++ b/libcxx/include/__cxx03/__random/subtract_with_carry_engine.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_SUBTRACT_WITH_CARRY_ENGINE_H -#define _LIBCPP___RANDOM_SUBTRACT_WITH_CARRY_ENGINE_H +#ifndef _LIBCPP___CXX03___RANDOM_SUBTRACT_WITH_CARRY_ENGINE_H +#define _LIBCPP___CXX03___RANDOM_SUBTRACT_WITH_CARRY_ENGINE_H #include <__cxx03/__algorithm/equal.h> #include <__cxx03/__algorithm/min.h> @@ -273,4 +273,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_SUBTRACT_WITH_CARRY_ENGINE_H +#endif // _LIBCPP___CXX03___RANDOM_SUBTRACT_WITH_CARRY_ENGINE_H diff --git a/libcxx/include/__cxx03/__random/uniform_int_distribution.h b/libcxx/include/__cxx03/__random/uniform_int_distribution.h index 8e509fad15774..2e4656bd503f6 100644 --- a/libcxx/include/__cxx03/__random/uniform_int_distribution.h +++ b/libcxx/include/__cxx03/__random/uniform_int_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H -#define _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_UNIFORM_INT_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_UNIFORM_INT_DISTRIBUTION_H #include <__cxx03/__bit/countl.h> #include <__cxx03/__config> @@ -261,4 +261,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_UNIFORM_INT_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_UNIFORM_INT_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/uniform_random_bit_generator.h b/libcxx/include/__cxx03/__random/uniform_random_bit_generator.h index 74bbea38bf207..37c10a1ddfbd9 100644 --- a/libcxx/include/__cxx03/__random/uniform_random_bit_generator.h +++ b/libcxx/include/__cxx03/__random/uniform_random_bit_generator.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_UNIFORM_RANDOM_BIT_GENERATOR_H -#define _LIBCPP___RANDOM_UNIFORM_RANDOM_BIT_GENERATOR_H +#ifndef _LIBCPP___CXX03___RANDOM_UNIFORM_RANDOM_BIT_GENERATOR_H +#define _LIBCPP___CXX03___RANDOM_UNIFORM_RANDOM_BIT_GENERATOR_H #include <__cxx03/__concepts/arithmetic.h> #include <__cxx03/__concepts/invocable.h> @@ -41,4 +41,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_UNIFORM_RANDOM_BIT_GENERATOR_H +#endif // _LIBCPP___CXX03___RANDOM_UNIFORM_RANDOM_BIT_GENERATOR_H diff --git a/libcxx/include/__cxx03/__random/uniform_real_distribution.h b/libcxx/include/__cxx03/__random/uniform_real_distribution.h index 64c978906a4ce..623344455ee31 100644 --- a/libcxx/include/__cxx03/__random/uniform_real_distribution.h +++ b/libcxx/include/__cxx03/__random/uniform_real_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_UNIFORM_REAL_DISTRIBUTION_H -#define _LIBCPP___RANDOM_UNIFORM_REAL_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_UNIFORM_REAL_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_UNIFORM_REAL_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/generate_canonical.h> @@ -135,4 +135,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_UNIFORM_REAL_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_UNIFORM_REAL_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__random/weibull_distribution.h b/libcxx/include/__cxx03/__random/weibull_distribution.h index 6c5937aaad9e7..83bb88d50f626 100644 --- a/libcxx/include/__cxx03/__random/weibull_distribution.h +++ b/libcxx/include/__cxx03/__random/weibull_distribution.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANDOM_WEIBULL_DISTRIBUTION_H -#define _LIBCPP___RANDOM_WEIBULL_DISTRIBUTION_H +#ifndef _LIBCPP___CXX03___RANDOM_WEIBULL_DISTRIBUTION_H +#define _LIBCPP___CXX03___RANDOM_WEIBULL_DISTRIBUTION_H #include <__cxx03/__config> #include <__cxx03/__random/exponential_distribution.h> @@ -129,4 +129,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANDOM_WEIBULL_DISTRIBUTION_H +#endif // _LIBCPP___CXX03___RANDOM_WEIBULL_DISTRIBUTION_H diff --git a/libcxx/include/__cxx03/__ranges/access.h b/libcxx/include/__cxx03/__ranges/access.h index a6a0470afeacd..23b61946a16bb 100644 --- a/libcxx/include/__cxx03/__ranges/access.h +++ b/libcxx/include/__cxx03/__ranges/access.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_ACCESS_H -#define _LIBCPP___RANGES_ACCESS_H +#ifndef _LIBCPP___CXX03___RANGES_ACCESS_H +#define _LIBCPP___CXX03___RANGES_ACCESS_H #include <__cxx03/__concepts/class_or_enum.h> #include <__cxx03/__config> @@ -207,4 +207,4 @@ inline constexpr auto cend = __cend::__fn{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_ACCESS_H +#endif // _LIBCPP___CXX03___RANGES_ACCESS_H diff --git a/libcxx/include/__cxx03/__ranges/all.h b/libcxx/include/__cxx03/__ranges/all.h index 0cb834fc41a35..57497f83478b5 100644 --- a/libcxx/include/__cxx03/__ranges/all.h +++ b/libcxx/include/__cxx03/__ranges/all.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_ALL_H -#define _LIBCPP___RANGES_ALL_H +#ifndef _LIBCPP___CXX03___RANGES_ALL_H +#define _LIBCPP___CXX03___RANGES_ALL_H #include <__cxx03/__config> #include <__cxx03/__functional/compose.h> // TODO(modules): Those should not be required @@ -75,4 +75,4 @@ using all_t = decltype(views::all(std::declval<_Range>())); _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_ALL_H +#endif // _LIBCPP___CXX03___RANGES_ALL_H diff --git a/libcxx/include/__cxx03/__ranges/as_rvalue_view.h b/libcxx/include/__cxx03/__ranges/as_rvalue_view.h index 011939f19ab0f..42234dabaf081 100644 --- a/libcxx/include/__cxx03/__ranges/as_rvalue_view.h +++ b/libcxx/include/__cxx03/__ranges/as_rvalue_view.h @@ -6,8 +6,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_AS_RVALUE_H -#define _LIBCPP___RANGES_AS_RVALUE_H +#ifndef _LIBCPP___CXX03___RANGES_AS_RVALUE_H +#define _LIBCPP___CXX03___RANGES_AS_RVALUE_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__concepts/same_as.h> @@ -139,4 +139,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_AS_RVALUE_H +#endif // _LIBCPP___CXX03___RANGES_AS_RVALUE_H diff --git a/libcxx/include/__cxx03/__ranges/chunk_by_view.h b/libcxx/include/__cxx03/__ranges/chunk_by_view.h index 8f17d56e5e93b..2b5c4d607c417 100644 --- a/libcxx/include/__cxx03/__ranges/chunk_by_view.h +++ b/libcxx/include/__cxx03/__ranges/chunk_by_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_CHUNK_BY_VIEW_H -#define _LIBCPP___RANGES_CHUNK_BY_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_CHUNK_BY_VIEW_H +#define _LIBCPP___CXX03___RANGES_CHUNK_BY_VIEW_H #include <__cxx03/__algorithm/ranges_adjacent_find.h> #include <__cxx03/__assert> @@ -232,4 +232,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_CHUNK_BY_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_CHUNK_BY_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/common_view.h b/libcxx/include/__cxx03/__ranges/common_view.h index 5af8de542dad9..e7022ff63abba 100644 --- a/libcxx/include/__cxx03/__ranges/common_view.h +++ b/libcxx/include/__cxx03/__ranges/common_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_COMMON_VIEW_H -#define _LIBCPP___RANGES_COMMON_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_COMMON_VIEW_H +#define _LIBCPP___CXX03___RANGES_COMMON_VIEW_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__concepts/copyable.h> @@ -139,4 +139,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_COMMON_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_COMMON_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/concepts.h b/libcxx/include/__cxx03/__ranges/concepts.h index 238d02cc2f68f..958a81c19bfa7 100644 --- a/libcxx/include/__cxx03/__ranges/concepts.h +++ b/libcxx/include/__cxx03/__ranges/concepts.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_CONCEPTS_H -#define _LIBCPP___RANGES_CONCEPTS_H +#ifndef _LIBCPP___CXX03___RANGES_CONCEPTS_H +#define _LIBCPP___CXX03___RANGES_CONCEPTS_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__concepts/movable.h> @@ -139,4 +139,4 @@ concept viewable_range = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_CONCEPTS_H +#endif // _LIBCPP___CXX03___RANGES_CONCEPTS_H diff --git a/libcxx/include/__cxx03/__ranges/container_compatible_range.h b/libcxx/include/__cxx03/__ranges/container_compatible_range.h index 7bf8218e667d0..9e47449fe50ab 100644 --- a/libcxx/include/__cxx03/__ranges/container_compatible_range.h +++ b/libcxx/include/__cxx03/__ranges/container_compatible_range.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H -#define _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H +#ifndef _LIBCPP___CXX03___RANGES_CONTAINER_COMPATIBLE_RANGE_H +#define _LIBCPP___CXX03___RANGES_CONTAINER_COMPATIBLE_RANGE_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__config> @@ -30,4 +30,4 @@ concept _ContainerCompatibleRange = _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_CONTAINER_COMPATIBLE_RANGE_H +#endif // _LIBCPP___CXX03___RANGES_CONTAINER_COMPATIBLE_RANGE_H diff --git a/libcxx/include/__cxx03/__ranges/counted.h b/libcxx/include/__cxx03/__ranges/counted.h index a20a4824b03cd..a4a11cd0064b9 100644 --- a/libcxx/include/__cxx03/__ranges/counted.h +++ b/libcxx/include/__cxx03/__ranges/counted.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_COUNTED_H -#define _LIBCPP___RANGES_COUNTED_H +#ifndef _LIBCPP___CXX03___RANGES_COUNTED_H +#define _LIBCPP___CXX03___RANGES_COUNTED_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__config> @@ -86,4 +86,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_COUNTED_H +#endif // _LIBCPP___CXX03___RANGES_COUNTED_H diff --git a/libcxx/include/__cxx03/__ranges/dangling.h b/libcxx/include/__cxx03/__ranges/dangling.h index fee2712ac829b..d57eca19b1c30 100644 --- a/libcxx/include/__cxx03/__ranges/dangling.h +++ b/libcxx/include/__cxx03/__ranges/dangling.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_DANGLING_H -#define _LIBCPP___RANGES_DANGLING_H +#ifndef _LIBCPP___CXX03___RANGES_DANGLING_H +#define _LIBCPP___CXX03___RANGES_DANGLING_H #include <__cxx03/__config> #include <__cxx03/__ranges/access.h> @@ -39,4 +39,4 @@ using borrowed_iterator_t = _If, iterator_t<_Rp>, dangling>; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_DANGLING_H +#endif // _LIBCPP___CXX03___RANGES_DANGLING_H diff --git a/libcxx/include/__cxx03/__ranges/data.h b/libcxx/include/__cxx03/__ranges/data.h index 2e38f210804da..80e473d218614 100644 --- a/libcxx/include/__cxx03/__ranges/data.h +++ b/libcxx/include/__cxx03/__ranges/data.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_DATA_H -#define _LIBCPP___RANGES_DATA_H +#ifndef _LIBCPP___CXX03___RANGES_DATA_H +#define _LIBCPP___CXX03___RANGES_DATA_H #include <__cxx03/__concepts/class_or_enum.h> #include <__cxx03/__config> @@ -99,4 +99,4 @@ inline constexpr auto cdata = __cdata::__fn{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_DATA_H +#endif // _LIBCPP___CXX03___RANGES_DATA_H diff --git a/libcxx/include/__cxx03/__ranges/drop_view.h b/libcxx/include/__cxx03/__ranges/drop_view.h index 9d1336fc877ed..78e0a26e4c7e9 100644 --- a/libcxx/include/__cxx03/__ranges/drop_view.h +++ b/libcxx/include/__cxx03/__ranges/drop_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_DROP_VIEW_H -#define _LIBCPP___RANGES_DROP_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_DROP_VIEW_H +#define _LIBCPP___CXX03___RANGES_DROP_VIEW_H #include <__cxx03/__algorithm/min.h> #include <__cxx03/__assert> @@ -326,4 +326,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_DROP_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_DROP_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/drop_while_view.h b/libcxx/include/__cxx03/__ranges/drop_while_view.h index 0542908a6cb5a..604dd29742a90 100644 --- a/libcxx/include/__cxx03/__ranges/drop_while_view.h +++ b/libcxx/include/__cxx03/__ranges/drop_while_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_DROP_WHILE_VIEW_H -#define _LIBCPP___RANGES_DROP_WHILE_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_DROP_WHILE_VIEW_H +#define _LIBCPP___CXX03___RANGES_DROP_WHILE_VIEW_H #include <__cxx03/__algorithm/ranges_find_if_not.h> #include <__cxx03/__assert> @@ -133,4 +133,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_DROP_WHILE_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_DROP_WHILE_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/elements_view.h b/libcxx/include/__cxx03/__ranges/elements_view.h index 515562719039b..9db16cde83be5 100644 --- a/libcxx/include/__cxx03/__ranges/elements_view.h +++ b/libcxx/include/__cxx03/__ranges/elements_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_ELEMENTS_VIEW_H -#define _LIBCPP___RANGES_ELEMENTS_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_ELEMENTS_VIEW_H +#define _LIBCPP___CXX03___RANGES_ELEMENTS_VIEW_H #include <__cxx03/__compare/three_way_comparable.h> #include <__cxx03/__concepts/constructible.h> @@ -415,4 +415,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_ELEMENTS_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_ELEMENTS_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/empty.h b/libcxx/include/__cxx03/__ranges/empty.h index 957fed827b404..c72a17ecaf19d 100644 --- a/libcxx/include/__cxx03/__ranges/empty.h +++ b/libcxx/include/__cxx03/__ranges/empty.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_EMPTY_H -#define _LIBCPP___RANGES_EMPTY_H +#ifndef _LIBCPP___CXX03___RANGES_EMPTY_H +#define _LIBCPP___CXX03___RANGES_EMPTY_H #include <__cxx03/__concepts/class_or_enum.h> #include <__cxx03/__config> @@ -68,4 +68,4 @@ inline constexpr auto empty = __empty::__fn{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_EMPTY_H +#endif // _LIBCPP___CXX03___RANGES_EMPTY_H diff --git a/libcxx/include/__cxx03/__ranges/empty_view.h b/libcxx/include/__cxx03/__ranges/empty_view.h index 265575baf678d..11a77de6a3392 100644 --- a/libcxx/include/__cxx03/__ranges/empty_view.h +++ b/libcxx/include/__cxx03/__ranges/empty_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_EMPTY_VIEW_H -#define _LIBCPP___RANGES_EMPTY_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_EMPTY_VIEW_H +#define _LIBCPP___CXX03___RANGES_EMPTY_VIEW_H #include <__cxx03/__config> #include <__cxx03/__ranges/enable_borrowed_range.h> @@ -51,4 +51,4 @@ inline constexpr empty_view<_Tp> empty{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_EMPTY_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_EMPTY_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/enable_borrowed_range.h b/libcxx/include/__cxx03/__ranges/enable_borrowed_range.h index 81051f67c003c..462053e35535d 100644 --- a/libcxx/include/__cxx03/__ranges/enable_borrowed_range.h +++ b/libcxx/include/__cxx03/__ranges/enable_borrowed_range.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H -#define _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H +#ifndef _LIBCPP___CXX03___RANGES_ENABLE_BORROWED_RANGE_H +#define _LIBCPP___CXX03___RANGES_ENABLE_BORROWED_RANGE_H // These customization variables are used in and . The // separate header is used to avoid including the entire header in @@ -37,4 +37,4 @@ inline constexpr bool enable_borrowed_range = false; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_ENABLE_BORROWED_RANGE_H +#endif // _LIBCPP___CXX03___RANGES_ENABLE_BORROWED_RANGE_H diff --git a/libcxx/include/__cxx03/__ranges/enable_view.h b/libcxx/include/__cxx03/__ranges/enable_view.h index 4697dab872bcf..b8d78c29064b7 100644 --- a/libcxx/include/__cxx03/__ranges/enable_view.h +++ b/libcxx/include/__cxx03/__ranges/enable_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_ENABLE_VIEW_H -#define _LIBCPP___RANGES_ENABLE_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_ENABLE_VIEW_H +#define _LIBCPP___CXX03___RANGES_ENABLE_VIEW_H #include <__cxx03/__concepts/derived_from.h> #include <__cxx03/__concepts/same_as.h> @@ -48,4 +48,4 @@ inline constexpr bool enable_view = derived_from<_Tp, view_base> || requires { _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_ENABLE_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_ENABLE_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/filter_view.h b/libcxx/include/__cxx03/__ranges/filter_view.h index 5015140c39ae7..b9beadb136652 100644 --- a/libcxx/include/__cxx03/__ranges/filter_view.h +++ b/libcxx/include/__cxx03/__ranges/filter_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_FILTER_VIEW_H -#define _LIBCPP___RANGES_FILTER_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_FILTER_VIEW_H +#define _LIBCPP___CXX03___RANGES_FILTER_VIEW_H #include <__cxx03/__algorithm/ranges_find_if.h> #include <__cxx03/__assert> @@ -257,4 +257,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_FILTER_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_FILTER_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/from_range.h b/libcxx/include/__cxx03/__ranges/from_range.h index 55ff79edd513d..2f0c827f827fe 100644 --- a/libcxx/include/__cxx03/__ranges/from_range.h +++ b/libcxx/include/__cxx03/__ranges/from_range.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_FROM_RANGE_H -#define _LIBCPP___RANGES_FROM_RANGE_H +#ifndef _LIBCPP___CXX03___RANGES_FROM_RANGE_H +#define _LIBCPP___CXX03___RANGES_FROM_RANGE_H #include <__cxx03/__config> @@ -30,4 +30,4 @@ inline constexpr from_range_t from_range{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_FROM_RANGE_H +#endif // _LIBCPP___CXX03___RANGES_FROM_RANGE_H diff --git a/libcxx/include/__cxx03/__ranges/iota_view.h b/libcxx/include/__cxx03/__ranges/iota_view.h index 5bc2394dc3dc2..5fa1e8151af20 100644 --- a/libcxx/include/__cxx03/__ranges/iota_view.h +++ b/libcxx/include/__cxx03/__ranges/iota_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_IOTA_VIEW_H -#define _LIBCPP___RANGES_IOTA_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_IOTA_VIEW_H +#define _LIBCPP___CXX03___RANGES_IOTA_VIEW_H #include <__cxx03/__assert> #include <__cxx03/__compare/three_way_comparable.h> @@ -401,4 +401,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_IOTA_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_IOTA_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/istream_view.h b/libcxx/include/__cxx03/__ranges/istream_view.h index 8db34132af59c..b54dc137690a0 100644 --- a/libcxx/include/__cxx03/__ranges/istream_view.h +++ b/libcxx/include/__cxx03/__ranges/istream_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_ISTREAM_VIEW_H -#define _LIBCPP___RANGES_ISTREAM_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_ISTREAM_VIEW_H +#define _LIBCPP___CXX03___RANGES_ISTREAM_VIEW_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__concepts/derived_from.h> @@ -138,4 +138,4 @@ _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_STD_VER >= 20 -#endif // _LIBCPP___RANGES_ISTREAM_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_ISTREAM_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/join_view.h b/libcxx/include/__cxx03/__ranges/join_view.h index ea47eeefcf951..3496fc9810704 100644 --- a/libcxx/include/__cxx03/__ranges/join_view.h +++ b/libcxx/include/__cxx03/__ranges/join_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_JOIN_VIEW_H -#define _LIBCPP___RANGES_JOIN_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_JOIN_VIEW_H +#define _LIBCPP___CXX03___RANGES_JOIN_VIEW_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__concepts/convertible_to.h> @@ -420,4 +420,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_JOIN_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_JOIN_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/lazy_split_view.h b/libcxx/include/__cxx03/__ranges/lazy_split_view.h index 9e70c237b4fb2..8dc05e0ec6f95 100644 --- a/libcxx/include/__cxx03/__ranges/lazy_split_view.h +++ b/libcxx/include/__cxx03/__ranges/lazy_split_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_LAZY_SPLIT_VIEW_H -#define _LIBCPP___RANGES_LAZY_SPLIT_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_LAZY_SPLIT_VIEW_H +#define _LIBCPP___CXX03___RANGES_LAZY_SPLIT_VIEW_H #include <__cxx03/__algorithm/ranges_find.h> #include <__cxx03/__algorithm/ranges_mismatch.h> @@ -438,4 +438,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_LAZY_SPLIT_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_LAZY_SPLIT_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/movable_box.h b/libcxx/include/__cxx03/__ranges/movable_box.h index ab6f407ed537b..7dc8b95b28bb4 100644 --- a/libcxx/include/__cxx03/__ranges/movable_box.h +++ b/libcxx/include/__cxx03/__ranges/movable_box.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_MOVABLE_BOX_H -#define _LIBCPP___RANGES_MOVABLE_BOX_H +#ifndef _LIBCPP___CXX03___RANGES_MOVABLE_BOX_H +#define _LIBCPP___CXX03___RANGES_MOVABLE_BOX_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__concepts/copyable.h> @@ -244,4 +244,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_MOVABLE_BOX_H +#endif // _LIBCPP___CXX03___RANGES_MOVABLE_BOX_H diff --git a/libcxx/include/__cxx03/__ranges/non_propagating_cache.h b/libcxx/include/__cxx03/__ranges/non_propagating_cache.h index 6f8c8600bab10..0db1914e592ba 100644 --- a/libcxx/include/__cxx03/__ranges/non_propagating_cache.h +++ b/libcxx/include/__cxx03/__ranges/non_propagating_cache.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H -#define _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H +#ifndef _LIBCPP___CXX03___RANGES_NON_PROPAGATING_CACHE_H +#define _LIBCPP___CXX03___RANGES_NON_PROPAGATING_CACHE_H #include <__cxx03/__config> #include <__cxx03/__iterator/concepts.h> // indirectly_readable @@ -100,4 +100,4 @@ struct __empty_cache {}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_NON_PROPAGATING_CACHE_H +#endif // _LIBCPP___CXX03___RANGES_NON_PROPAGATING_CACHE_H diff --git a/libcxx/include/__cxx03/__ranges/owning_view.h b/libcxx/include/__cxx03/__ranges/owning_view.h index ab7e4e3eeb974..5519d2c795c85 100644 --- a/libcxx/include/__cxx03/__ranges/owning_view.h +++ b/libcxx/include/__cxx03/__ranges/owning_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_OWNING_VIEW_H -#define _LIBCPP___RANGES_OWNING_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_OWNING_VIEW_H +#define _LIBCPP___CXX03___RANGES_OWNING_VIEW_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__concepts/movable.h> @@ -113,4 +113,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_OWNING_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_OWNING_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/range_adaptor.h b/libcxx/include/__cxx03/__ranges/range_adaptor.h index ef7301d695848..ef08464234b57 100644 --- a/libcxx/include/__cxx03/__ranges/range_adaptor.h +++ b/libcxx/include/__cxx03/__ranges/range_adaptor.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_RANGE_ADAPTOR_H -#define _LIBCPP___RANGES_RANGE_ADAPTOR_H +#ifndef _LIBCPP___CXX03___RANGES_RANGE_ADAPTOR_H +#define _LIBCPP___CXX03___RANGES_RANGE_ADAPTOR_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__concepts/derived_from.h> @@ -98,4 +98,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_RANGE_ADAPTOR_H +#endif // _LIBCPP___CXX03___RANGES_RANGE_ADAPTOR_H diff --git a/libcxx/include/__cxx03/__ranges/rbegin.h b/libcxx/include/__cxx03/__ranges/rbegin.h index 3e114605baf37..8f987319cc4fe 100644 --- a/libcxx/include/__cxx03/__ranges/rbegin.h +++ b/libcxx/include/__cxx03/__ranges/rbegin.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_RBEGIN_H -#define _LIBCPP___RANGES_RBEGIN_H +#ifndef _LIBCPP___CXX03___RANGES_RBEGIN_H +#define _LIBCPP___CXX03___RANGES_RBEGIN_H #include <__cxx03/__concepts/class_or_enum.h> #include <__cxx03/__concepts/same_as.h> @@ -117,4 +117,4 @@ inline constexpr auto crbegin = __crbegin::__fn{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_RBEGIN_H +#endif // _LIBCPP___CXX03___RANGES_RBEGIN_H diff --git a/libcxx/include/__cxx03/__ranges/ref_view.h b/libcxx/include/__cxx03/__ranges/ref_view.h index 9fd2835cf385c..43c3bebe34dc3 100644 --- a/libcxx/include/__cxx03/__ranges/ref_view.h +++ b/libcxx/include/__cxx03/__ranges/ref_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_REF_VIEW_H -#define _LIBCPP___RANGES_REF_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_REF_VIEW_H +#define _LIBCPP___CXX03___RANGES_REF_VIEW_H #include <__cxx03/__concepts/convertible_to.h> #include <__cxx03/__concepts/different_from.h> @@ -86,4 +86,4 @@ inline constexpr bool enable_borrowed_range> = true; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_REF_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_REF_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/rend.h b/libcxx/include/__cxx03/__ranges/rend.h index 9d663e54f4619..aa7e4a0ba396a 100644 --- a/libcxx/include/__cxx03/__ranges/rend.h +++ b/libcxx/include/__cxx03/__ranges/rend.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_REND_H -#define _LIBCPP___RANGES_REND_H +#ifndef _LIBCPP___CXX03___RANGES_REND_H +#define _LIBCPP___CXX03___RANGES_REND_H #include <__cxx03/__concepts/class_or_enum.h> #include <__cxx03/__concepts/same_as.h> @@ -120,4 +120,4 @@ inline constexpr auto crend = __crend::__fn{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_REND_H +#endif // _LIBCPP___CXX03___RANGES_REND_H diff --git a/libcxx/include/__cxx03/__ranges/repeat_view.h b/libcxx/include/__cxx03/__ranges/repeat_view.h index fae883e01bcfe..a0cd065b9f2aa 100644 --- a/libcxx/include/__cxx03/__ranges/repeat_view.h +++ b/libcxx/include/__cxx03/__ranges/repeat_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_REPEAT_VIEW_H -#define _LIBCPP___RANGES_REPEAT_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_REPEAT_VIEW_H +#define _LIBCPP___CXX03___RANGES_REPEAT_VIEW_H #include <__cxx03/__assert> #include <__cxx03/__concepts/constructible.h> @@ -263,4 +263,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_REPEAT_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_REPEAT_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/reverse_view.h b/libcxx/include/__cxx03/__ranges/reverse_view.h index 7513114779c5a..53a0e9d213c5b 100644 --- a/libcxx/include/__cxx03/__ranges/reverse_view.h +++ b/libcxx/include/__cxx03/__ranges/reverse_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_REVERSE_VIEW_H -#define _LIBCPP___RANGES_REVERSE_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_REVERSE_VIEW_H +#define _LIBCPP___CXX03___RANGES_REVERSE_VIEW_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__config> @@ -200,4 +200,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_REVERSE_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_REVERSE_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/single_view.h b/libcxx/include/__cxx03/__ranges/single_view.h index 34054fa0f9d42..3e43302f213b1 100644 --- a/libcxx/include/__cxx03/__ranges/single_view.h +++ b/libcxx/include/__cxx03/__ranges/single_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_SINGLE_VIEW_H -#define _LIBCPP___RANGES_SINGLE_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_SINGLE_VIEW_H +#define _LIBCPP___CXX03___RANGES_SINGLE_VIEW_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__config> @@ -108,4 +108,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_SINGLE_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_SINGLE_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/size.h b/libcxx/include/__cxx03/__ranges/size.h index 84b165551d921..f311f76df15cc 100644 --- a/libcxx/include/__cxx03/__ranges/size.h +++ b/libcxx/include/__cxx03/__ranges/size.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_SIZE_H -#define _LIBCPP___RANGES_SIZE_H +#ifndef _LIBCPP___CXX03___RANGES_SIZE_H +#define _LIBCPP___CXX03___RANGES_SIZE_H #include <__cxx03/__concepts/arithmetic.h> #include <__cxx03/__concepts/class_or_enum.h> @@ -134,4 +134,4 @@ inline constexpr auto ssize = __ssize::__fn{}; _LIBCPP_END_NAMESPACE_STD -#endif // _LIBCPP___RANGES_SIZE_H +#endif // _LIBCPP___CXX03___RANGES_SIZE_H diff --git a/libcxx/include/__cxx03/__ranges/split_view.h b/libcxx/include/__cxx03/__ranges/split_view.h index f23e7878e349c..76ab9f485bd7c 100644 --- a/libcxx/include/__cxx03/__ranges/split_view.h +++ b/libcxx/include/__cxx03/__ranges/split_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_SPLIT_VIEW_H -#define _LIBCPP___RANGES_SPLIT_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_SPLIT_VIEW_H +#define _LIBCPP___CXX03___RANGES_SPLIT_VIEW_H #include <__cxx03/__algorithm/ranges_search.h> #include <__cxx03/__concepts/constructible.h> @@ -229,4 +229,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_SPLIT_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_SPLIT_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/subrange.h b/libcxx/include/__cxx03/__ranges/subrange.h index fa985a5c365af..e077d221ed202 100644 --- a/libcxx/include/__cxx03/__ranges/subrange.h +++ b/libcxx/include/__cxx03/__ranges/subrange.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_SUBRANGE_H -#define _LIBCPP___RANGES_SUBRANGE_H +#ifndef _LIBCPP___CXX03___RANGES_SUBRANGE_H +#define _LIBCPP___CXX03___RANGES_SUBRANGE_H #include <__cxx03/__assert> #include <__cxx03/__concepts/constructible.h> @@ -270,4 +270,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_SUBRANGE_H +#endif // _LIBCPP___CXX03___RANGES_SUBRANGE_H diff --git a/libcxx/include/__cxx03/__ranges/take_view.h b/libcxx/include/__cxx03/__ranges/take_view.h index e909158f5c417..d3cadd55ae1c1 100644 --- a/libcxx/include/__cxx03/__ranges/take_view.h +++ b/libcxx/include/__cxx03/__ranges/take_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_TAKE_VIEW_H -#define _LIBCPP___RANGES_TAKE_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_TAKE_VIEW_H +#define _LIBCPP___CXX03___RANGES_TAKE_VIEW_H #include <__cxx03/__algorithm/min.h> #include <__cxx03/__algorithm/ranges_min.h> @@ -366,4 +366,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_TAKE_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_TAKE_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/take_while_view.h b/libcxx/include/__cxx03/__ranges/take_while_view.h index 3968777240ed2..7dec8490e0754 100644 --- a/libcxx/include/__cxx03/__ranges/take_while_view.h +++ b/libcxx/include/__cxx03/__ranges/take_while_view.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_TAKE_WHILE_VIEW_H -#define _LIBCPP___RANGES_TAKE_WHILE_VIEW_H +#ifndef _LIBCPP___CXX03___RANGES_TAKE_WHILE_VIEW_H +#define _LIBCPP___CXX03___RANGES_TAKE_WHILE_VIEW_H #include <__cxx03/__concepts/constructible.h> #include <__cxx03/__concepts/convertible_to.h> @@ -167,4 +167,4 @@ _LIBCPP_END_NAMESPACE_STD _LIBCPP_POP_MACROS -#endif // _LIBCPP___RANGES_TAKE_WHILE_VIEW_H +#endif // _LIBCPP___CXX03___RANGES_TAKE_WHILE_VIEW_H diff --git a/libcxx/include/__cxx03/__ranges/to.h b/libcxx/include/__cxx03/__ranges/to.h index 682b811946a62..f50f43cccc53a 100644 --- a/libcxx/include/__cxx03/__ranges/to.h +++ b/libcxx/include/__cxx03/__ranges/to.h @@ -7,8 +7,8 @@ // //===----------------------------------------------------------------------===// -#ifndef _LIBCPP___RANGES_TO_H -#define _LIBCPP___RANGES_TO_H +#ifndef _LIBCPP___CXX03___RANGES_TO_H +#define _LIBCPP___CXX03___RANGES_TO_H #include <__cxx03/__algorithm/ranges_copy.h> #include <__cxx03/__concepts/constructible.h> @@ -242,4 +242,4 @@ template